摘要

运动底盘是移动机器人的重要组成部分,不像激光雷达、IMU、麦克风、音响、摄像头这些通用部件可以直接买到,很难买到通用的底盘。一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的;另一方面是因为底盘包含软硬件整套解决方案,是很多机器人公司的核心技术,一般不会随便公开。出于强烈的求知欲与学习热情,我想自己DIY一整套两轮差分底盘,并且将完整的设计过程公开出去供大家学习。说干就干,本章节主要内容:

1.stm32主控硬件设计

2.stm32主控软件设计

3.底盘通信协议

4.底盘ROS驱动开发

5.底盘PID控制参数整定

6.底盘里程计标



2.stm32主控软件设计

上一节搭建好了底盘的stm32主控硬件,现在就来说说怎么开发配套的stm32软件。关于建立stm32工程、使用stm32开发库、stm32软件调试方法等基础知识就不多说了,有需要的可以查阅相关资料学习,我觉得http://www.openedv.com《正点原子》的开发资料写的还可以。我就直接从底盘控制的项目入手,直接进行项目中各个功能需求开始分析讲解,如图11,是我的底盘控制stm32工程项目。

(图11)底盘控制stm32工程项目

2.1.电机控制

电机控制分为两个部分(电机转向控制、电机转速控制),这些都集成在了电机驱动芯片TB6612FNG里面,所以只需要用单片机的IO口产生控制转向的高低电平和控制转速的PWM波就能实现。

首先,初始化IO口作为输出脚,用于产生高低电平输出来控制转向,实例代码如图12。

(图12)电机转向控制IO口初始化

然后,用通用定时器TIM4的通道CH1和CH2分别产生两路PWM输出用于两个电机的转速控制,定时器默认引脚分配如图13。

(图13)stm32定时器通道默认引脚分配

初始化通用定时器TIM4的通道CH1和CH2为PWM输出,实例代码如14。

(图14)电机转速控制IO口初始化

最后,将电机转向和速度控制的操作封装在一个函数中,便于其它地方调用,实例代码如图15。

(图15)电机转向和速度控制封装

2.2.编码器数据读取

编码器对底盘来说至关重要,一方面底盘通过编码器的反馈进行PID闭环速度控制,另一方面底盘通过编码器进行航迹推演得到里程计用于后续的定位与导航等高级算法中。这里用到的编码器是正交编码器,所以直接使用通用定时器的输入捕获中的编码器模式来读取编码器。采用通用定时器TIM2的通道CH1和CH2捕获encoder1的A相和B相脉冲,采用通用定时器TIM3的通道CH1和CH2捕获encoder2的A相和B相脉冲。

先初始化TIM2作为编码器encoder1的捕获,实例代码如图16。

(图16)初始化TIM2作为编码器encoder1的捕获

然后,将读取编码器计数值的操作封装在一个函数中,便于其它地方调用,实例代码如图17。

(图17)读取编码器encoder1计数值封装

最后,编写TIM2计数溢出时的中断处理函数,实例代码如图18。

(图18)TIM2计数溢出中断处理函数

同理可得TIM3捕获encoder2的代码实现,这里就不在赘述了。

2.3.串口数据收发

串口2是数据接口,负责接收上位机发送过来的控制指令,同时将编码器值返回给上位机;串口1是debug接口,负责接收上位机发送过来的版本信息请求、PIDm默认值恢复、PID值设定等调试指令,同时将程序中的debug打印信息返回给上位机。但是在底盘正常工作时,只需要连接串口2;串口1是预留出来给有需要自己动手修改PID参数使用的。

首先,配置串口1,先对串口1的输出进行printf函数打印支持,实例代码如图19。

(图19)串口1的输出进行printf函数打印支持

然后,初始化串口1,实例代码如图20。

(图20)初始化串口1

最后,编写串口1接收中断处理函数,此函数主要进行对上位机发过来的数据进行协议解析,实例代码如图21。

(图21)串口1接收中断处理函数

接下来,介绍串口2,初始化串口2,实例代码如图22。

(图22)初始化串口2

然后,将串口2发送数据的操作封装到函数中,便于其它地方调用,实例代码如图23。

(图23)串口2发送数据封装

最后,编写串口2接收中断处理函数,此函数主要进行对上位机发过来的数据进行协议解析,实例代码如图24。

(图24)串口2接收中断处理函数

到这里,串口有1和串口2的数据发送与接收都编写好了,依据我们定义的usart2数据通信协议和usart1调试通信协议,上位机就可以编写对应的程序来跟底盘的串口2和串口1进行通信了。关于通信协议的具体内容,将在后续做展开。

2.4.电机速度PID控制

我在底盘中采用的是增量型PID算法,编程涉及到的数学表达式有3个,分别是:

e(k) = target_value - current_value

delta_u(k) = Kp*[e(k)-e(k-1)] + Ki*e(k) + Kd*[e(k)-2*e(k-1)+e(k-2)]

u(k) = u(k-1) + delta_u(k)

将这3个数学表达式封装到函数中,便于其它地方调用,实例代码如图25。

(图25)串口2接收中断处理函数

电机1与电机2采用同样的PID算法,所以电机2的PID算法代码实现就不赘述了。关于PID参数的整定方法,将在后续做展开。

2.5.周期性控制

通过上面的讲解,各个模块的驱动代码都准备就绪了,现在需要产生一个周期性的过程,在里面实现编码器计数值采样、PID控制等具体实现。这里采用定时器TIM1产生一个周期性的中断,在中断处理函数中实现各模块的具体操作。

首先,配置定时器TIM1,实例代码如图26。

(图26)配置定时器TIM1

然后,编写中断处理函数,实例代码如图27。

(图27)TIM1中断处理函数

2.6.stm32主控软件整体框图

通过上面的讲解,对底盘控制的stm32程序实现有了一定的了解,接下来就来做一个总结。

先来看看main()函数实现,如图28。

(图28)main()函数实现

结合上面TIM1中断处理函数,不难发现,整个stm32程序的执行过程:

a.在main()函数中初始化各个模块;

b.TIM1中断处理函数周期性的读取编码器值、反馈获取的编码值、PID控制;

c.剩下的就是串口1和串口2的通信交互。

具体stm32主控软件整体框图如图29。

(图29)stm32主控软件整体框图

需要说明的是,在周期性循环体中,要首先读取编码器的值,来保证严格的等间隔采样。

后记

------SLAM+语音机器人DIY系列【目录】快速导览------

第1章:Linux基础

1.Linux简介

2.安装Linux发行版ubuntu系统

3.Linux命令行基础操作

第2章:ROS入门

1.ROS是什么

2.ROS系统整体架构

3.在ubuntu16.04中安装ROS kinetic

4.如何编写ROS的第一个程序hello_world

5.编写简单的消息发布器和订阅器

6.编写简单的service和client

7.理解tf的原理

8.理解roslaunch在大型项目中的作用

9.熟练使用rviz

10.在实际机器人上运行ROS高级功能预览

第3章:感知与大脑

1.ydlidar-x4激光雷达

2.带自校准九轴数据融合IMU惯性传感器

3.轮式里程计与运动控制

4.音响麦克风与摄像头

5.机器人大脑嵌入式主板性能对比

6.做一个能走路和对话的机器人

第4章:差分底盘设计

1.stm32主控硬件设计

2.stm32主控软件设计

3.底盘通信协议

4.底盘ROS驱动开发

5.底盘PID控制参数整定

6.底盘里程计标

第5章:树莓派3开发环境搭建

1.安装系统ubuntu_mate_16.04

2.安装ros-kinetic

3.装机后一些实用软件安装和系统设置

4.PC端与robot端ROS网络通信

5.Android手机端与robot端ROS网络通信

6.树莓派USB与tty串口号绑定

7.开机自启动ROS节点

第6章:SLAM建图与自主避障导航

1.在机器人上使用传感器

2.google-cartographer机器人SLAM建图

3.ros-navigation机器人自主避障导航

4.多目标点导航及任务调度

5.机器人巡航与现场监控

第7章:语音交互与自然语言处理

1.语音交互相关技术

2.机器人语音交互实现

3.自然语言处理云计算引擎

第8章:高阶拓展

1.miiboo机器人安卓手机APP开发

2.centos7下部署Django(nginx+uwsgi+django+python3)

----------------文章将持续更新,敬请关注-----------------

如果大家对博文的相关类容感兴趣,或有什么技术疑问,欢迎加入下面的《SLAM+语音机器人DIY》QQ技术交流群,一起讨论学习^_^

SLAM+语音机器人DIY系列:(四)差分底盘设计——2.stm32主控软件设计的更多相关文章

  1. SLAM+语音机器人DIY系列:(四)差分底盘设计——6.底盘里程计标

    摘要 运动底盘是移动机器人的重要组成部分,不像激光雷达.IMU.麦克风.音响.摄像头这些通用部件可以直接买到,很难买到通用的底盘.一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的:另一方面是因为 ...

  2. SLAM+语音机器人DIY系列:(四)差分底盘设计——1.stm32主控硬件设计

    摘要 运动底盘是移动机器人的重要组成部分,不像激光雷达.IMU.麦克风.音响.摄像头这些通用部件可以直接买到,很难买到通用的底盘.一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的:另一方面是因为 ...

  3. SLAM+语音机器人DIY系列:(四)差分底盘设计——3.底盘通信协议

    摘要 运动底盘是移动机器人的重要组成部分,不像激光雷达.IMU.麦克风.音响.摄像头这些通用部件可以直接买到,很难买到通用的底盘.一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的:另一方面是因为 ...

  4. SLAM+语音机器人DIY系列:(四)差分底盘设计——4.底盘ROS驱动开发

    摘要 运动底盘是移动机器人的重要组成部分,不像激光雷达.IMU.麦克风.音响.摄像头这些通用部件可以直接买到,很难买到通用的底盘.一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的:另一方面是因为 ...

  5. SLAM+语音机器人DIY系列:(四)差分底盘设计——5.底盘PID控制参数整定

    摘要 运动底盘是移动机器人的重要组成部分,不像激光雷达.IMU.麦克风.音响.摄像头这些通用部件可以直接买到,很难买到通用的底盘.一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的:另一方面是因为 ...

  6. SLAM+语音机器人DIY系列:(二)ROS入门——1.ROS是什么

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  7. SLAM+语音机器人DIY系列:(三)感知与大脑——4.音响麦克风与摄像头

    摘要 在我的想象中机器人首先应该能自由的走来走去,然后应该能流利的与主人对话.朝着这个理想,我准备设计一个能自由行走,并且可以与人语音对话的机器人.实现的关键是让机器人能通过传感器感知周围环境,并通过 ...

  8. SLAM+语音机器人DIY系列:(三)感知与大脑——5.机器人大脑嵌入式主板性能对比

    摘要 在我的想象中机器人首先应该能自由的走来走去,然后应该能流利的与主人对话.朝着这个理想,我准备设计一个能自由行走,并且可以与人语音对话的机器人.实现的关键是让机器人能通过传感器感知周围环境,并通过 ...

  9. SLAM+语音机器人DIY系列:(三)感知与大脑——6.做一个能走路和对话的机器人

    摘要 在我的想象中机器人首先应该能自由的走来走去,然后应该能流利的与主人对话.朝着这个理想,我准备设计一个能自由行走,并且可以与人语音对话的机器人.实现的关键是让机器人能通过传感器感知周围环境,并通过 ...

随机推荐

  1. rand ----MATLAB (经典)

    最近一直在学习matlab,我相信有一些同学已经发现,最近更新的关于matlab的内容比较多, 希望能够帮助到未来的小学弟学妹们! 永远爱你们的 ----新宝宝 rand 均匀分布的随机数全页折叠 语 ...

  2. java基于BasicPlayer调用 播放音乐

    无聊中想想用java调用下听音乐的api.晚上很多文章用的比较老大方法了,都是用原生的代码写,而且不支持mp3格式,BasicPlayer第三方包提供了很好的api调用,简单的3行代码就可以调用mp3 ...

  3. GT工具中用到的英文词解释

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px ".PingFang SC"; color: #454545 } p.p2 ...

  4. css中常见margin塌陷问题之解决办法

    塌陷问题 当两个盒子在垂直方向上设置margin值时,会出现一个有趣的塌陷现象. ①垂直并列 首先设置两个DIV,并为其制定宽高 1 /*HTML部分*/ 2 <body> 3 <d ...

  5. 使用 ASP.NET Core MVC 创建 Web API(五)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...

  6. .Net Core ORM选择之路,哪个才适合你

    因为老板的一句话公司项目需要迁移到.Net Core ,但是以前同事用的ORM不支持.Net Core 开发过程也遇到了各种坑,插入条数多了也特别的慢,导致系统体验比较差好多都改写Sql实现. 所以我 ...

  7. Dynamics 365 CE的插件/自定义工作流活动中调用Web API示例代码

    微软动态CRM专家罗勇 ,回复325或者20190428可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! 现在Web API越来越流行,有时候为了程序更加健壮,需要在插件 ...

  8. 在github上fork项目如何同步并解决冲突

    在github上fork项目如何同步并解决冲突 在github上有些项目我们可能会进行一些自己功能的添加但是提交PR后作者基于设计或者其他原因考虑没有通过,但是这个功能又是我们必须的.这时我们就想自己 ...

  9. 事务及其特性ACID

    一.事务的定义 事务是一组单元化的操作,这组操作可以保证要么全部成功,要么全部失败(只要有一个失败的操作,就会把其他已经成功的操作回滚). 一般所说的数据库事务,它是访问并可能更新数据库中各种数据项的 ...

  10. C语言中#undef作用

    #undef 作用:取消定义的宏 指令格式:#undef 标识符 1 #include <stdio.h> 2 3 #define MAX 5 4 5 int main() { 6 pri ...