我现在想用maixcam和rt1064来完成小车巡线的功能
这个是rt1064的代码
#include "zf_common_headfile.h"
#include <stdlib.h>
#include <string.h>
#define PWM_LEFT PWM1_MODULE3_CHB_D1 // ???PWM
#define PWM_RIGHT PWM2_MODULE3_CHA_D2 // ???PWM
#define BASE_SPEED 3000
#define KP 50
#define MAX_TURN_ADJUSTMENT 3000
#define LINE_LOST_THRESHOLD 0 // ???XL?XR?0
extern char g_uart_rx_buffer[32];
extern volatile uint8_t g_data_frame_ready;
extern volatile int16 g_maixcam_XL;
extern volatile int16 g_maixcam_XR;
int last_valid_error = 0;
uint8_t last_XL = 120;
uint8_t last_XR = 120;
bool has_valid_data = false;
// ??????
bool is_line_lost(uint8_t XL, uint8_t XR)
{
return (XL == LINE_LOST_THRESHOLD && XR == LINE_LOST_THRESHOLD);
}
// ??????
void parse_maixcam_data(void)
{
__disable_irq();
if (g_uart_rx_buffer[0] == (char)0xA3 && g_uart_rx_buffer[1] == (char)0xB3 &&
g_uart_rx_buffer[5] == (char)0xC3)
{
g_maixcam_XL = (uint8_t)g_uart_rx_buffer[2];
g_maixcam_XR = (uint8_t)g_uart_rx_buffer[3];
}
g_data_frame_ready = 0;
memset(g_uart_rx_buffer, 0, sizeof(g_uart_rx_buffer));
__enable_irq();
}
void update_motor_speed(uint8_t XL, uint8_t XR)
{
int center = (XL + XR) / 2;
int error = 120 - center;
int abs_error = error > 0 ? error : -error;
int turn = KP * error;
if (turn > MAX_TURN_ADJUSTMENT) turn = MAX_TURN_ADJUSTMENT;
if (turn < -MAX_TURN_ADJUSTMENT) turn = -MAX_TURN_ADJUSTMENT;
int left, right;
if (abs_error > 40)
{
if (error > 0) // ????
{
left = 0;
right = BASE_SPEED + turn; // turn??
if (right > PWM_DUTY_MAX) right = PWM_DUTY_MAX;
}
else // ????
{
right = 0;
left = BASE_SPEED - turn; // turn??
if (left > PWM_DUTY_MAX) left = PWM_DUTY_MAX;
}
}
else // ??????????
{
left = BASE_SPEED - turn;
right = BASE_SPEED + turn;
if (left < 0) left = 0;
if (right < 0) right = 0;
if (left > PWM_DUTY_MAX) left = PWM_DUTY_MAX;
if (right > PWM_DUTY_MAX) right = PWM_DUTY_MAX;
}
pwm_set_duty(PWM_LEFT, left);
pwm_set_duty(PWM_RIGHT, right);
}
int main(void)
{
clock_init(SYSTEM_CLOCK_600M);
debug_init();
pwm_init(PWM_LEFT, 17000, 0);
pwm_init(PWM_RIGHT, 17000, 0);
oled_init();
oled_clear();
oled_show_string(0, 0, "Line Tracker");
uart1_interrupt_init(); // ???????MaixCAM
while (1)
{
if (g_data_frame_ready)
{
parse_maixcam_data();
if (!is_line_lost(g_maixcam_XL, g_maixcam_XR))
{
last_XL = g_maixcam_XL;
last_XR = g_maixcam_XR;
has_valid_data = true;
oled_show_string(0, 2, "Found ");
oled_show_int(60, 2, last_XL, 3);
oled_show_int(60, 4, last_XR, 3);
}
else
{
oled_show_string(0, 2, "Lost ");
}
if (has_valid_data)
{
update_motor_speed(last_XL, last_XR);
}
else
{
pwm_set_duty(PWM_LEFT, 0);
pwm_set_duty(PWM_RIGHT, 0);
oled_show_string(0, 2, "Waiting");
}
}
}
这个是maixcam的代码
from maix import touchscreen, camera, display, app, image, uart, time
disp = display.Display()
ts = touchscreen.TouchScreen()
cam = camera.Camera(240, 180)
img = image.Image(240, 180)
device = "/dev/ttyS0"
serial = uart.UART(device, 115200)
thresholds = [[0, 46, -45, 11, -55, 33]]
# thresholds = [[0, 80, -120, -10, 0, 30]] # green
# thresholds = [[0, 80, d:\\BaiduNetdiskDownload\\M0G3507\\M0G3507工程\\MAIN.py$030, 100, -120, -60]] # blue
t = time.time_s()
max_ID=[-1,-1]
XL=0
XR=0
range_stop=500
time0=0
time0last=0
laps=0
def is_in_button(x, y, btn_pos):
return x > btn_pos[0] and x < btn_pos[0] + btn_pos[2] and y > btn_pos[1] and y < btn_pos[1] + btn_pos[3]
def the_exit_button():
exit_label = "<Exit"
size = image.string_size(exit_label)
exit_btn_pos = [0, 0, 5*2 + size.width(), 5 * 2 + size.height()]
# draw exit button
img.draw_string(4, 8, exit_label, image.COLOR_WHITE)
# 图像按键坐标映射到屏幕上的坐标
exit_btn_disp_pos = image.resize_map_pos(img.width(), img.height(), disp.width(), disp.height(), image.Fit.FIT_CONTAIN, exit_btn_pos[0], exit_btn_pos[1], exit_btn_pos[2], exit_btn_pos[3])
x, y, pressed = ts.read()
if is_in_button(x, y, exit_btn_disp_pos):
app.set_exit_flag(True)
def find_max(blobs):
max_size=[0,0]
max_ID=[-1,-1]
for i in range(len(blobs)):
if blobs[i].pixels()>max_size[0]:
max_ID[1]=max_ID[0]
max_size[1]=max_size[0]
max_ID[0]=i
max_size[0]=blobs[i].pixels()
elif blobs[i].pixels()>max_size[1]:
max_ID[1]=i
max_size[1]=blobs[i].pixels()
return max_ID
while not app.need_exit():
XL=120
XR=120
time0=time.time_s()-t
img = cam.read()
img.draw_string(20, 30, str(laps), image.COLOR_WHITE)
img.draw_string(40, 30, str(time0), image.COLOR_WHITE)
blobs = img.find_blobs(thresholds,roi=[20, 120, 200, 40], pixels_threshold=1,merge=True)
if blobs:
max_ID=[-1,-1]
max_ID=find_max(blobs) #找最大色块
img.draw_rect(blobs[max_ID[0]][0],blobs[max_ID[0]][1],blobs[max_ID[0]][2], blobs[max_ID[0]][3], image.COLOR_GREEN)
img.draw_cross(blobs[max_ID[0]].cx(),blobs[max_ID[0]].cy(),image.COLOR_GREEN)
XL=blobs[max_ID[0]].cx()
XR=XL
img.draw_string(80, 8, str(XR), image.COLOR_WHITE)
img.draw_string(80, 30, str(blobs[max_ID[0]].pixels()), image.COLOR_WHITE)
if max_ID[1]!=-1:
img.draw_rect(blobs[max_ID[1]][0],blobs[max_ID[1]][1],blobs[max_ID[1]][2], blobs[max_ID[1]][3], image.COLOR_GREEN)
img.draw_cross(blobs[max_ID[1]].cx(),blobs[max_ID[1]].cy(),image.COLOR_GREEN)
if(blobs[max_ID[0]].cx()>blobs[max_ID[1]].cx()):
XL=blobs[max_ID[1]].cx()
XR=blobs[max_ID[0]].cx()
else:
XL=blobs[max_ID[0]].cx()
XR=blobs[max_ID[1]].cx()
else:
if (blobs[max_ID[0]].pixels()>range_stop and time0 - time0last >= 7):
laps=laps+1
time0last=time0
the_exit_button()
data = bytearray([0xa3,0xb3,XL,XR,laps,0xc3])
print(data)
serial.write(bytes(data))
disp.show(img) 我发现小车并不能很好的拐弯,拐了一些就不拐了,直接直走,我希望你帮我看看什么原因