描述
以下两篇文章将是这一系列最后的两篇,将对全部的代码进行剖析
开发的时间并不多,有些写的并不是最优的实现,请多指教
代码
mian.c
添加的代码段就多了
增加头文件和一些变量定义
/* USER CODE BEGIN Includes */
#include "control.h"
#define RXBUFFERSIZE 256
char info_buffer[RXBUFFERSIZE];
uint8_t aRxBuffer;
uint8_t Uart1_Rx_Cnt = 0;
#define MAGNETIC_BUFFER_LEN 8
uint8_t magnetic_buffer[MAGNETIC_BUFFER_LEN];
uint8_t Uart3_Rx_Cnt = 0;
#define CARD_BUFFER_LEN 16
uint8_t card_buffer[CARD_BUFFER_LEN];
uint8_t Uart6_Rx_Cnt = 0;
#define ULTRASONIC_BUFFER_LEN 4
uint8_t ultrasonic_left_buffer[ULTRASONIC_BUFFER_LEN];
uint8_t ultrasonic_right_buffer[ULTRASONIC_BUFFER_LEN];
enum Motor_state g_motor;
struct Robot g_robot;
struct Command g_command;
#include "ws2812.h"
int direction = 6;
uint8_t g_value_r[LED_NUM] = {0x00};
uint8_t g_value_b[LED_NUM] = {0x00};
uint8_t g_value_g[LED_NUM] = {0x00};
/* USER CODE END Includes */
这部分代码一坨,我来总结一下干了什么事儿吧
机器人初始化、电机使能和失能等。这些代码在main函数之前的同级函数,会在main函数中进行调用
/* USER CODE BEGIN 0 */
int get_key_status(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
if (HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == GPIO_PIN_SET)
{
while(HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == GPIO_PIN_SET);
return 1;
}
else
{
return 0;
}
}
int robot_init()
{
g_robot.m_speed = MOTOR_SPEED_INITIAL;
g_robot.m_motor_left_value = MOTOR_SPEED_INITIAL;
g_robot.m_motor_right_value = MOTOR_SPEED_INITIAL;
//g_robot.m_motor_right_value = -g_robot.m_motor_right_value ;
g_robot.m_target = -1;
g_robot.m_robot_status = READY;
g_robot.m_direction = 1;
g_robot.m_is_derailed = 0;
g_robot.m_change_derailed_first = 0;
g_robot.m_is_blocked = 0;
g_robot.m_change_block_first = 0;
g_robot.m_obstacle_left_distance = OBSTACLE_DISTANCE_MIN+1;
g_robot.m_obstacle_right_distance = OBSTACLE_DISTANCE_MIN+1;
for (int i = 0 ; i < OBSTACLE_SMOOTH_NUM ; i ++)
{
g_robot.m_obstacle_left_distance_memory[i] = OBSTACLE_DISTANCE_MIN +1;
g_robot.m_obstacle_right_distance_memory[i] = OBSTACLE_DISTANCE_MIN +1;
}
g_robot.m_obstacle_left_distance_sum = (OBSTACLE_DISTANCE_MIN +1 )*OBSTACLE_SMOOTH_NUM;
g_robot.m_obstacle_right_distance_sum = (OBSTACLE_DISTANCE_MIN +1 )*OBSTACLE_SMOOTH_NUM;
g_motor = MOTOR_DISABLE;
return 0;
}
int robot_enable()
{
if (g_motor == MOTOR_DISABLE)
{
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
g_motor = MOTOR_ENABLE;
// printf("< robot > robot enable!\n");
}
else
{
//printf("< robot > already enable!\n");
}
return 0;
}
int robot_disable()
{
if (g_motor == MOTOR_ENABLE)
{
HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_2);
HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_2);
g_motor = MOTOR_DISABLE;
// printf("< robot > robot disable!\n");
}
else
{
//printf("< robot > already disable!\n");
}
return 0;
}
int robot_run(int motor_left_value, int motor_right_value)
{
robot_enable();
if (g_robot.m_direction == 1)
{
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, motor_left_value);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 0);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, motor_right_value);
}
else
{
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, abs(motor_left_value));
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, abs(motor_right_value));
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
}
g_robot.m_robot_status = RUNNING;
//printf("< robot > running! left speed: %d, right speed: %d, direction: %d\n",
//g_robot.m_motor_left_value, g_robot.m_motor_right_value, g_robot.m_direction);
return 0;
}
int robot_speed_up(int value)
{
g_robot.m_speed = g_robot.m_speed + value * g_robot.m_direction;
if (abs(g_robot.m_speed) >= abs(MOTOR_SPEED_MAX))
{
g_robot.m_speed = MOTOR_SPEED_MAX * g_robot.m_direction;
}
if (abs(g_robot.m_speed) <= abs(MOTOR_SPEED_MIN))
{
g_robot.m_speed = MOTOR_SPEED_MIN * g_robot.m_direction;
}
return 0;
}
int robot_speed_down(int value)
{
g_robot.m_speed = g_robot.m_speed - value * g_robot.m_direction;
if (abs(g_robot.m_speed) >= abs(MOTOR_SPEED_MAX))
{
g_robot.m_speed = MOTOR_SPEED_MAX * g_robot.m_direction;
}
if (abs(g_robot.m_speed) <= abs(MOTOR_SPEED_MIN))
{
g_robot.m_speed = MOTOR_SPEED_MIN * g_robot.m_direction;
}
return 0;
}
int robot_direction_reverse()
{
g_robot.m_direction = - g_robot.m_direction;
g_robot.m_speed = -g_robot.m_speed;
return 0;
}
// 检查机器人是否脱轨(磁传感器)
void check_derail(void)
{
int j = 0;
while(g_robot.m_magnetic_status_0_1[j] == 0 && j < MAGNETIC_BUFFER_LEN)
{
j++;
}
if (j == MAGNETIC_BUFFER_LEN) // 如果磁条传感器的所有通道值都为1
{
g_robot.m_is_derailed = 1; // 将机器人的脱轨状态变量赋值为1, 代表脱轨了
}
else
{
g_robot.m_is_derailed = 0; // 将机器人的脱轨状态变量赋值为0, 代表没有脱轨
}
}
// 检查机器人是否被障碍物挡住(超声传感器)
void check_block(void)
{
// 如果左右传感器的值,均小于距离 阈值
if (g_robot.m_obstacle_left_distance < OBSTACLE_DISTANCE_MIN || g_robot.m_obstacle_right_distance < OBSTACLE_DISTANCE_MIN )
{
//g_robot.m_is_blocked = 1; // 将机器人的障碍状态变量赋值为1, 代表被障碍物阻塞
}
else
{
g_robot.m_is_blocked = 0; // 将机器人的障碍状态变量赋值为0, 代表没有障碍
}
}
// 检查并更新机器人的状态
void check_robot_status(void)
{
check_derail(); // 检查磁条传感器,确定脱轨状态变量m_is_blocked
check_block(); // 检查超声传感器,确定障碍状态变量m_is_blocked
// 状态机更新的原则
// 脱轨后,将永远保持DERAILED,直到start命令改变m_change_derailed_first变量
// 第一次阻塞后,记住之前的状态;当不在阻塞时,需要恢复到之前的状态
if (g_robot.m_change_derailed_first == 0) // 之前一直是没有脱轨的状态
{
if (g_robot.m_is_derailed == 1) // 如果一旦脱轨了
{
g_robot.m_robot_status = DERAILED; // 机器人的状态设置为DERAILED
g_robot.m_change_derailed_first = 1; // 将不会再进入最外层if函数(只有start命令可以改变此变量)
}
else // 如果机器人没有脱轨
{
if (g_robot.m_is_blocked == 1 ) // 如果机器人前方有障碍物
{
if (g_robot.m_change_block_first == 0) // 如果这是第一次被挡住
{
g_robot.m_robot_status_last = g_robot.m_robot_status; // 需要记住被挡住前的状态(READY 或 RUNNING)
g_robot.m_change_block_first = 1; // 用m_change_block_first这个标志变量,确保只进入这个if函数一次,这样才能记住block前的状态
}
g_robot.m_robot_status = BLOCK; // 机器人的状态设置为BLOCK
}
else // 如果机器人没有脱轨也没有被挡住
{
// 之前的状态为BLOCK,需要从阻塞状态中恢复时
if (g_robot.m_change_block_first == 1) // 从block第一次恢复为之前的READY或RUNNING,只进入这个函数一次
{
HAL_Delay(2000);
g_robot.m_robot_status = g_robot.m_robot_status_last;
g_robot.m_change_block_first = 0;
}
// 一直是正常状态,不需要做任何处理
else
{
}
}
}
}
}
// 处理灯光的颜色,确保灯光颜色与机器人状态完全一致
void process_led()
{
if (g_robot.m_robot_status == READY) // 青色:机器人准备就绪,或者正常停下
{
for (uint8_t i = 0 ; i < LED_NUM; i++)
{
g_value_r[i] = 0x00; g_value_g[i] = 0xFF; g_value_b[i] = 0xFF;
}
}
else if (g_robot.m_robot_status == BLOCK) // 黄色:机器人被障碍阻塞
{
for (uint8_t i = 0 ; i < LED_NUM; i++)
{
g_value_r[i] = 0xFF; g_value_g[i] = 0xFF; g_value_b[i] = 0x00;
}
}
else if (g_robot.m_robot_status == RUNNING) // 绿色:机器人正在运动
{
for (uint8_t i = 0 ; i < LED_NUM; i++)
{
g_value_r[i] = 0x00; g_value_g[i] = 0xFF; g_value_b[i] = 0x00;
}
}
else if (g_robot.m_robot_status == DERAILED) // 红色:机器人脱轨
{
for (uint8_t i = 0 ; i < LED_NUM; i++)
{
g_value_r[i] = 0xFF; g_value_g[i] = 0x00; g_value_b[i] = 0x00;
}
}
// 设置灯的颜色
for (uint8_t i = 0 ; i < LED_NUM; i++)
{
led_set(i, g_value_r[i], g_value_g[i], g_value_b[i]);
}
// 开灯
led_on();
}
// 机器人开机的灯光效果
void led_turnon(void)
{
int j = 51;
int k_min = 50;
int k_max = 52;
int phase = 1;
while (j > 22)
{
for (uint8_t i = 0 ; i < LED_NUM; i++)
{
g_value_r[i] = 0x00;
if (phase == 1)
{
if ( i < k_max && i > k_min)
{
g_value_g[i] = 0xFF;g_value_b[i] = 0xFF;
}
else
{
g_value_g[i] = 0x00;g_value_b[i] = 0x00;
}
}
if (phase == 2)
{
if ( i > k_max || i < k_min)
{
g_value_g[i] = 0xFF;g_value_b[i] = 0xFF;
}
else
{
g_value_g[i] = 0x00;g_value_b[i] = 0x00;
}
}
led_set(i, g_value_r[i], g_value_g[i], g_value_b[i]);
}
j++;
HAL_Delay(100);
led_on();
if (k_max == 60)
{
phase = 2;
k_max = k_min;
k_min = -1;
}
if (phase == 1)
{
k_max = k_max + 1;
k_min = k_min - 1;
}
else if (phase == 2)
{
k_max = k_max - 1;
k_min = k_min + 1;
}
if ( k_min > 22 && phase == 2 )
{
break;
}
}
}
/* USER CODE END 0 */
开机后运行一次
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
HAL_UART_Receive_IT(&huart2, magnetic_buffer, MAGNETIC_BUFFER_LEN);
HAL_UART_Receive_IT(&huart3, card_buffer, CARD_BUFFER_LEN);
HAL_UART_Receive_IT(&huart4, ultrasonic_left_buffer, ULTRASONIC_BUFFER_LEN);
HAL_UART_Receive_IT(&huart5, ultrasonic_right_buffer, ULTRASONIC_BUFFER_LEN);
robot_init();
printf("hello FUXI ROBOT!\n");
led_init();
led_turnon(); // turn , because magnetic module donnot send message to our brain
printf("FUXI ROBOT IS READY!\n");
/* USER CODE END 2 */
在main函数中不断循环的部分
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
// 磁条传感器及超声传感器,都需要在while循环中打开串口接收,否则数据只可以收到一次(暂时不懂为什么这样)
HAL_UART_Receive_IT(&huart2, magnetic_buffer, MAGNETIC_BUFFER_LEN);
HAL_UART_Receive_IT(&huart4, ultrasonic_left_buffer, ULTRASONIC_BUFFER_LEN);
HAL_UART_Receive_IT(&huart5, ultrasonic_right_buffer, ULTRASONIC_BUFFER_LEN);
// 主循环中不停的检查机器人的状态
check_robot_status();
// 灯根据机器人的状态及时改变
process_led();
}
/* USER CODE END 3 */
用于处理各个传感器信息中断的代码
/* USER CODE BEGIN 4 */
int robot_walk_forward(){return 0;};
int robot_walk_rear(){return 0;};
int robot_walk_left(){return 0;};
int robot_walk_right(){return 0;};
int process_magnetic(uint8_t magnetic_buffer[MAGNETIC_BUFFER_LEN])
{
uint8_t magnetic_value = magnetic_buffer[5];
struct Robot r;
r = translate_magnetic_2_motor(g_robot, magnetic_value);
g_robot.m_motor_left_value = r.m_motor_left_value;
g_robot.m_motor_right_value = r.m_motor_right_value;
g_robot.m_magnetic_value = r.m_magnetic_value;
for (int i = 0 ; i < MAGNETIC_BUFFER_LEN; i++)
{
g_robot.m_magnetic_status_0_1[i] = r.m_magnetic_status_0_1[i];
}
if (g_robot.m_robot_status == RUNNING )
{
robot_run(r.m_motor_left_value, r.m_motor_right_value);
}
else if (g_robot.m_robot_status == DERAILED || g_robot.m_robot_status == BLOCK)
{
robot_disable();
}
return 0;
}
int process_card(int card_id)
{
if (card_id == g_robot.m_target)
{
printf("< robot > arrived target %d!\n", card_id);
g_robot.m_target = -1;
g_robot.m_robot_status = READY;
robot_disable();
}
else
{
printf("< robot > arrived at %d!\n", card_id);
}
printf("< robot > state: %d, speed: %d, target: %d, left: %d, right: %d, direction:%d\n",
g_robot.m_robot_status,
g_robot.m_speed,
g_robot.m_target,
g_robot.m_motor_left_value,
g_robot.m_motor_right_value,
g_robot.m_direction
);
return 0;
}
void process_ultrasonic(int channel)
{
int left_mean, right_mean;
if ( channel == 0)
{
//printf("left distance: %d!\n", g_robot.m_obstacle_left_distance);
left_mean = (g_robot.m_obstacle_left_distance_sum + g_robot.m_obstacle_left_distance - g_robot.m_obstacle_left_distance_memory[0]) / OBSTACLE_SMOOTH_NUM;
for (int i = 0 ; i < OBSTACLE_SMOOTH_NUM -1 ; i++)
{
g_robot.m_obstacle_left_distance_memory[i] = g_robot.m_obstacle_left_distance_memory[i+1];
}
g_robot.m_obstacle_left_distance_memory[OBSTACLE_SMOOTH_NUM-1] = g_robot.m_obstacle_left_distance;
}
else
{
//printf("right distance: %d!\n", g_robot.m_obstacle_right_distance);
left_mean = (g_robot.m_obstacle_right_distance_sum + g_robot.m_obstacle_right_distance - g_robot.m_obstacle_right_distance_memory[0]) / OBSTACLE_SMOOTH_NUM;
for (int i = 0 ; i < OBSTACLE_SMOOTH_NUM -1 ; i++)
{
g_robot.m_obstacle_right_distance_memory[i] = g_robot.m_obstacle_right_distance_memory[i+1];
}
g_robot.m_obstacle_right_distance_memory[OBSTACLE_SMOOTH_NUM-1] = g_robot.m_obstacle_right_distance;
}
if ( left_mean< OBSTACLE_DISTANCE_MIN || right_mean < OBSTACLE_DISTANCE_MIN )
{
//g_robot.m_is_blocked = 1;
}
else
{
g_robot.m_is_blocked = 0;
}
}
int process_command(char info_buffer[256])
{
g_command = translate_infor_2_command(info_buffer);
switch (g_command.m_command_kind)
{
// 如果命令是"start"
case RUN:
// 首先检查机器人的状态
check_robot_status();
// "start"是最高级的控制指令,会忽视机器人的状态,只会考虑当前机器人是否脱轨或阻塞
// 机器人脱轨后,必须下发start命令,否则机器人的状态将一直保持为DERAILED,没有其他命令可以改变这个状态
// 如果机器人此时没有脱轨,也没有被障碍物阻塞
if (g_robot.m_is_derailed != 1 && g_robot.m_is_blocked != 1 ) // no block, no derailed,
{
// 可以让机器人开始运动
robot_run(g_robot.m_motor_left_value, g_robot.m_motor_right_value);
// 机器人的状态需要被设置成RUNNING
g_robot.m_robot_status = RUNNING;
g_robot.m_change_derailed_first = 0;
printf("< answer >< OK >[ start ]\n");
}
else if (g_robot.m_is_derailed == 1)
{
printf("< answer >< OK >[ cannot start ]: robot is derailed!\n");
}
else if (g_robot.m_is_blocked == 1)
{
printf("< answer >< OK >[ cannot start ]: robot is blocked!\n");
}
break;
case STOP:
if (g_robot.m_robot_status != DERAILED )
{
printf("< answer >< OK >[ stop ]\n");
robot_disable();
g_robot.m_robot_status = READY;
}
else
{
printf("< answer >< OK >[ already stop]: robot is derailed!\n");
}
break;
case SET_SPEED:
g_robot.m_speed = g_command.m_command_value; // speed can +/-
printf("< answer >< OK >[ set ][ speed ]: %d\n", g_robot.m_speed );
g_robot.m_motor_left_value = g_robot.m_speed;
g_robot.m_motor_right_value = g_robot.m_speed;
//g_robot.m_motor_right_value = - g_robot.m_motor_right_value;
if (g_robot.m_robot_status == RUNNING) // + no collision + no obstacle
{
if (g_robot.m_speed < 0)
{
g_robot.m_direction = -1;
}
else
{
g_robot.m_direction = 1;
}
robot_run(g_robot.m_motor_left_value, g_robot.m_motor_right_value);
}
break;
case SET_TARGET:
check_robot_status();
// 如果机器人当前的状态,不是脱轨,也不是阻塞
if (g_robot.m_robot_status != DERAILED && g_robot.m_robot_status != BLOCK )
{
g_robot.m_target = g_command.m_command_value;
printf("< answer >< OK >[ set ][ target ]: go to %d\n", g_robot.m_target);
robot_run(g_robot.m_motor_left_value, g_robot.m_motor_right_value);
g_robot.m_robot_status = RUNNING;
}
else if (g_robot.m_robot_status == DERAILED )
{
printf("< answer >< OK >[ cannot set ][ target ]: %d, robot is derailed!\n", g_robot.m_target);
}
else if (g_robot.m_robot_status == BLOCK)
{
printf("< answer >< OK >[ cannot set ][ target ]: %d, robot is blocked!\n", g_robot.m_target);
}
break;
case CHARGE:
check_robot_status();
// 如果机器人当前的状态,不是脱轨,也不是阻塞
if (g_robot.m_robot_status != DERAILED && g_robot.m_robot_status != BLOCK )
{
g_robot.m_target = g_command.m_command_value;
printf("< answer >< OK >[ charge ]\n");
robot_run(g_robot.m_motor_left_value, g_robot.m_motor_right_value);
g_robot.m_robot_status = RUNNING;
}
else if (g_robot.m_robot_status == DERAILED )
{
printf("< answer >< OK >[ cannot charge ] robot is derailed!\n");
}
else if (g_robot.m_robot_status == BLOCK)
{
printf("< answer >< OK >[ cannot charge ] robot is blocked!\n");
}
break;
case WALK_FORWARD:
printf("< answer >< OK >[ walk ][ forward ]\n");
robot_walk_forward();
robot_disable();
g_robot.m_robot_status = READY;
break;
case WALK_REAR:
printf("< answer >< OK >[ walk ][ rear ]\n");
robot_walk_rear();
robot_disable();
g_robot.m_robot_status = READY;
break;
case WALK_LEFT:
printf("< answer >< OK >[ walk ][ left ]\n");
robot_walk_left();
robot_disable();
g_robot.m_robot_status = READY;
break;
case WALK_RIGHT:
printf("< answer >< OK >[ walk ][ right ]\n");
robot_walk_right();
robot_disable();
g_robot.m_robot_status = READY;
break;
case QUERY_ALL:
query(g_robot, g_command, g_motor, 0);
break;
case QUERY_STATUS:
query(g_robot, g_command, g_motor, 1);
break;
case QUERY_SPEED:
query(g_robot, g_command, g_motor, 2);
break;
case QUERY_TARGET:
query(g_robot, g_command, g_motor, 3);
break;
case COMMAND_ERROR:
break;
}
printf("< robot > state: %d, speed: %d, target: %d, left: %d, right: %d, direction:%d\n",
g_robot.m_robot_status,
g_robot.m_speed,
g_robot.m_target,
g_robot.m_motor_left_value,
g_robot.m_motor_right_value,
g_robot.m_direction
);
return 0;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
if (huart == &huart1)
{
if(Uart1_Rx_Cnt >= 255)
{
Uart1_Rx_Cnt = 0;
memset(info_buffer,0x00,sizeof(info_buffer));
HAL_UART_Transmit(&huart1, (uint8_t *)"Data overflow!", 10,0xFFFF);
}
else
{
info_buffer[Uart1_Rx_Cnt++] = aRxBuffer;
if(info_buffer[Uart1_Rx_Cnt-3] == ';' && info_buffer[Uart1_Rx_Cnt-2] == 0x0D && info_buffer[Uart1_Rx_Cnt-1] == 0x0A)
{
process_command(info_buffer);
Uart1_Rx_Cnt = 0;
memset(info_buffer,0x00,sizeof(info_buffer));
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
}
if (huart == &huart2)
{
process_magnetic(magnetic_buffer);
HAL_UART_Receive_IT(&huart2, magnetic_buffer, MAGNETIC_BUFFER_LEN);
}
if (huart == &huart3)
{
uint8_t card_id = card_buffer[15];
process_card(card_id);
HAL_UART_Receive_IT(&huart3, card_buffer, CARD_BUFFER_LEN);
}
if (huart == &huart4)
{
uint8_t distance_high = ultrasonic_left_buffer[1];
uint8_t distance_low = ultrasonic_left_buffer[2];
uint8_t distance = distance_high * 256 + distance_low;
g_robot.m_obstacle_left_distance = distance;
process_ultrasonic(0);
HAL_UART_Receive_IT(&huart4, ultrasonic_left_buffer, ULTRASONIC_BUFFER_LEN);
}
if (huart == &huart5)
{
uint8_t distance_high = ultrasonic_right_buffer[1];
uint8_t distance_low = ultrasonic_right_buffer[2];
uint8_t distance = distance_high * 256 + distance_low;
g_robot.m_obstacle_right_distance = distance;
process_ultrasonic(1);
HAL_UART_Receive_IT(&huart5, ultrasonic_right_buffer, ULTRASONIC_BUFFER_LEN);
}
}
/* USER CODE END 4 */
这些代码都有注释,命名也是较为清晰的,对代码不做过多的解释。
总结
至此我们完成了一个磁条机器人的开发工作。我们也顺利的结束这一专栏吧。
之后我想会写一些关于AMR的知识和算法,敬请期待
评论(0)
您还未登录,请登录后发表或查看评论