机器人运动控制对主控制器计算实时性和伺服通讯可靠性要求很高,这里我们提供了一个在RT-Linux环境下基于QT作为开发的Demo,采用交叉编译的远程下载的开发模式。这里以官方主控套件中的ARM架构的Odroid-C4(如采用树莓派请参考知乎安装RT补打,并且下载官方树莓派官方桌面OS下载QT直接编译项目就可以;如采用Upboard则直接安装Ubuntu虚拟机安装QT直接编译即可)作为主控,对整个运动开发模式进行讲解,本项目开发参考了MIT等国外机器人项目的经验,具体流程如下图所示:
如上图所示整个开发框架为:
(1)在Ubuntu虚拟机中通过IDE完成运动控制代码开发,由于Odroid为ARM平台采用交叉编译得到固件,然后通过无线或有限方式将可执行文件传输到Odroid中;
(2)载板在Keil中完成STM32驱动开发,使用SWD完成下;(
(3)Odroid运行固件后通过SPI读取STM32姿态和关节数据反馈,然后下传伺服驱动指令;
(4)STM32完成IMU数据采集和姿态解算,通过SPI与主控通讯,使用CAN完成对节点或电机的通讯;
STM32 CAN载板工程解析
Can载板工程为STM32进行开发,其主要完成IMU采集、姿态解算、SPI主控通讯、参数存储以及CAN通讯,本项目最大的特点是采用DMA实现SPI通讯,从而实现了us级与主控间大容量数据的交互,相应开发例程可以参考“STM32开发部分”,各函数介绍如下:
(1)init.c
该函数为初始化函数,依次完成IO、CAN、SPI和Flash硬件的初始化:
该部分首先完成看门狗初始化,如主控不连接则载板会一直重启,因此如何要独立测试需要注释IWDG部分;下面完成CAN波特率的选择默认为2Mbps,如需使用其他波特率可以采用资料中STM32波特率计算软件配置;
(1)scheduler.c
线程调度函数,这里采用了裸奔的计时器调度,分别设定不同周期定时器完成不同的任务:
(1)姿态解算线程
本项目提高3个典型姿态解算引擎,分别是A.互补滤波;B.梯度下降;C.EKF姿态解算,通过在include.h中进行选择:
传感器数据采集结果可以查看mems结构体:
姿态解算结果可以查看vmc_all结构体:
(2)SPI通讯线程
A.本项目采用SPI与主控通讯,基于DMA实现自动收发完全不占用STM32有效的资源,并且实现了us级的数据同步。载板作为SPI从站,因此通讯时钟由主控决定,在Custom_SPI_Device.h中通过设置DataSize保证与主控可靠的通讯:
注:DataSize需要与Linux项目中设置的值一样,该值为载板和主控发送数据量中最大的一个,如主控SPI在协议中共发送100字节,而载板仅回传80字节,这里仍然要设置为100,载板在发送80字节后会继续发送20个空字节,这样保证上下数据的一致同步不会错位!
B.在spi.c中slave_send可以改变发送的协议:
C.在slave_rx中可以改变接收解码程序:
Linux-RT 工程解析
(1)Linux-RT程序首先在虚拟机中需要搭建QT开发环境,安装方法可以参考http://c.biancheng.net/view/3886.html。由于Odroid为ARM平台而Ubuntu虚拟机为X86平台,因此需要配置交叉编译。打开QT tools-options配置GCC和C++编译器,拷贝资料中的cross-gcc(1.1G压缩包)到虚拟机中,参考下面的例子分别修改编译器使用的地址:
GCC配置:
G++配置:
KIT配置:
解压Linux下的工程配置其采用新建立的交叉编译Kit,进行编译如无误后可以得到对应的可执行文件:
注:根据cmakelist中的路径配置最终产生的可执行文件hardware_task将会在不同的文件夹这里需要注意!
(2)在得到固件后,就可以采用无线或有线(UDroid联网参考之前的介绍)的方式将其传输到目标机中这也是Mini Cheetha所采用的方式,通过资料中的download.sh脚本进行下载,在拷贝到虚拟机后首先需要在控制台中对其授权sudo chmod +x download.sh。脚本中实际就是采用SSH完成对文件的拷贝:
scp ./build/*task2 odroid@192.168.1.120:/home/odroid/Corgi
其中需要注意拷贝的文件和目标机IP与目标地址;
(3)在估计下载后同样采用ssh odroid@192.168.1.120完成远程登录,在输入密码后,进入下载固件的地址,首次下载同样需要对其授权,之后采用sudo指令对其进行启动!
(4)main.cpp
与STM32驱动程序中描述一样,SPI时钟由主控决定,另外发送数据长度二者需要一致:
(5)Yaml参数管理
程序中默认读取了yaml文件,如系统中没有需要人为增加,或者注释代码中相应功能,如采购整套主控则已经建立相应工作目录:
(6)SPI发送
与单片机中类似SPI发送协议修改在:
(7)SPI接收
Linux下的SPI接收解码在:
注:项目工程中存在多个版本通讯协议,具体采用收发协议请参考代码中选择的ID!
(8)共享内存
Hardware实际是一个运动控制的底层任务,用户开发可以选择直接在该项目中建立多线程,在其他线程完成运动控制的计算,另外可以建立其他的进程采用共享内存完成二者间的通讯。后者的好处是一般情况下底层驱动任务修改不会很频繁,而运动控制会随调试修改,因此底层驱动任务可以作为独立任务,则采用共享内存向控制任务发送数据协议为:
从运动控制任务接收数据,解码协议为:
共享内存调度线程为:
注:pshm_rx->flag为内存读写互斥锁,即两任务分别检测该标志位不同状态来决定是否读写自己的数据!