一起来开发一个磁条机器人(五)
描述
这一篇介绍磁条机器人的算法思路,并开源部分代码
算法核心思路
磁条机器人的算法核心思路很简单,我愿意称之为“消息触发型”,意思就是机器人接收消息再通过代码进行判断和操作。
当然了,整体代码还是要分几部分去实现。以下几个小节来概述
消息处理
指令处理
上位机发送过来的命令,需要将命令解析,并对命令进行处理,令机器人做出相应的改变。
磁条信号处理
磁传感器的数据,由算法来判断磁条现在和机器人的位姿状态,改变左右电机的转速
RFID模块信息处理
RFID读到卡片后会产生中断信号,算法根据读到的卡片信息,来做相应的改变
超声信息处理
超声模块不停的将正前方距离数据返回,算法根据数值大小,判断机器人是否遇到障碍物
状态维护
机器人自身信息
需要维护的数据信息有很多,这些信息都需要在运行过程中被维护,包括机器人自身的状态、上一时刻的状态、左右电机的当前转速,设置的最大转速、运行方向、收到的命令、是否有目标点、目标点卡号等等。
不一一列出,这些在代码中或通过全局常量或通过struct进行动态调整,总之将全部的信息维护好很重要,这样即使出现问题我们可以知道机器人究竟发生了什么。
状态切换
机器人在运行过程中,最重要的就是状态。机器人出现问题,我们常问的也是,机器人现在是什么状态啊。因此机器人状态机的切换是尤为关键的。
机器人遇到什么状况转换成什么状态机,除了改变算法中的一些变量,另外一个要做的就是改变状态灯。这让我们能够很好的判断机器人的宏观运行状态。
为此我们另开一个小节,专门来讲一下我算法设置的机器人状态
状态介绍
我的算法中,将机器人状态分为4类,分别是READY,BLOCK,RUNNING,DERAILED,它们分别代表的顾名思义就是准备运行、有障碍、正常运行、脱轨。机器人在运行过程中的全部状态,都可以分为这四类。
(以下涉及到的命令会在之后的篇章中做出解释)
READY
含义:机器人准备好去运行
状态转入:机器人开机后,到达指定目标后,接收到stop命令后,会进入READY状态
状态转出:在这一状态下,机器人收到start和to两种命令后,会转到状态RUNNING
灯:机器人常亮青色灯
BLOCK
含义:机器人被障碍物卡住
状态转入:目前只有超声传感器的数据能令机器人进入BLOCK状态
状态转出:前方障碍物消除后,BLOCK状态会自动恢复到阻塞之前的状态,不用人为干预
灯:机器人常亮黄色灯
RUNNING
含义:机器人正常运行
状态转入:收到start和to的前进命令后,而当前的状态为READY时,才会进入RUNNING;或由BLOCK恢复
状态转出:会因障碍物转为BLOCK,会因脱轨转为DERAILED,会因到达目标转为READY
灯:机器人常亮绿色灯
DERAILED
含义:机器人脱轨
状态转入:目前只有磁条传感器的数据能令机器人进入DERAILED 状态,只要磁传感器返回数据证证明没有检测到磁条,READY、BLOCK和RUNNING状态都可以转为DERAILED状态
状态转出:状态不可自动恢复,只有通过开关机将状态转为READY;或者经人为处理矫正后发送命令“start”命令,可以转为RUNNING
灯:机器人常亮红色灯
添加代码文件
添加.h文件
点击菜单栏中的魔法棒
在弹出的窗口找到“Include Paths”,在文件编辑框最后有一个“…”的按钮,点击
可以进入头文件添加的窗口,我们在这里面可以添加需要用到的头文件
添加.c文件
找到最左侧的项目文件树,可以发现“Application/User/Core”
右键点击后,选择“Add Existing files…”,就可以添加已经写好的.c文件了
代码详解
我们首先增加状态灯的两个文件,分别是ws2812.h和ws2812.c
ws2812.h
#ifndef __WS2812_LED_H__
#define __WS2812_LED_H__
#include "tim.h"
#define ONE_PULSE 54
#define ZERO_PULSE 26
#define LED_NUM 60
#define LED_DATA_LEN 24
#define RESET_PULSE_LEN 80
#define DATA_BUFFER_LEN RESET_PULSE_LEN+(LED_DATA_LEN*LED_NUM)
uint16_t static data_buffur[DATA_BUFFER_LEN] = { 0 };
void led_init(void);
void led_on(void);
void led_set(uint8_t led_id, uint8_t value_r, uint8_t value_g, uint8_t value_b);
#endif
ws2812.c
#include "ws2812.h"
void led_init(void)
{
for(uint8_t i = 0; i < LED_NUM; i++)
{
led_set(i, 0x00, 0x00, 0x00);
}
}
void led_set(uint8_t led_id, uint8_t value_r, uint8_t value_g, uint8_t value_b)
{
uint16_t* p = (data_buffur + RESET_PULSE_LEN) + (LED_DATA_LEN * led_id);
for (uint16_t i = 0; i < 8; i++)
{
p[i] = (value_g << i) & (0x80)? ONE_PULSE: ZERO_PULSE;
p[i + 8] = (value_r << i) & (0x80)? ONE_PULSE: ZERO_PULSE;
p[i + 16] = (value_b << i) & (0x80)? ONE_PULSE: ZERO_PULSE;
}
}
void led_on(void)
{
HAL_TIM_PWM_Start_DMA(&htim4, TIM_CHANNEL_1, (uint32_t *)data_buffur, DATA_BUFFER_LEN);
}
这两个文件的代码,将被主控用来控制状态灯的颜色。
总结
这篇文章暂时介绍到这儿,除了介绍算法的整体思路,还介绍了状态灯的代码文件。
接下来还有一篇文章,我们将全部的代码放到下一篇文章中,这样便于阅读
- 分享
- 举报
-
浏览量:745次2023-04-20 08:54:12
-
浏览量:798次2023-04-21 08:55:25
-
浏览量:1338次2023-04-20 08:57:01
-
浏览量:1021次2023-04-21 08:46:56
-
浏览量:818次2023-04-23 09:46:58
-
2023-12-06 11:28:37
-
浏览量:1263次2023-03-20 15:51:34
-
浏览量:6578次2022-05-30 15:26:15
-
浏览量:1084次2023-08-10 14:45:17
-
浏览量:987次2023-02-15 15:42:15
-
浏览量:464次2023-11-15 15:54:49
-
浏览量:639次2023-09-28 10:38:10
-
浏览量:2946次2020-11-18 14:34:59
-
浏览量:777次2023-09-20 11:37:44
-
浏览量:4085次2019-10-23 14:55:46
-
浏览量:1184次2023-10-28 16:11:07
-
浏览量:2262次2022-03-22 09:00:12
-
浏览量:1621次2023-02-25 10:56:42
-
浏览量:1649次2020-04-03 09:38:23
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
MOmo
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明