基于ROS 平台的移动机器人的设计与运动仿真摘要:ROS 究竟是如何工作的呢?ROS 中每一套算法是独立的一个包,包与包之间的数据交换主要采用TCP/IP 协议(对用户隐藏,用户需要发布或订阅主题以提供或取得数据),采用这种形式是由于ROS 的算法包是由全世界不同的个人,学校或实验室贡献的,这样做可以降低耦合性,如果一个node 崩溃不会影响到其他。
基于ROS 这个平台,有助于提高开发设计的效率及降低成本。
本论文主要阐述了基于ROS 平台移动机器人设计的基本原理和方法,并对移动机器人进行了运动仿真,得到其运动轨迹和控制方法,为后续项目的进一步研究打下了一定的基础。
0引言ROS 被称为机器人操作系统,其实ROS 充当的是通信中间件的角色,即在已有操作系统的基础上搭建了一整套针对机器人系统的实现框架。
ROS 还提供一组实用工具和软件库,用于维护、构建、编写和执行可用于多个计算平台的软件代码。
值得一提的是,ROS 的设计者考虑到各开发者使用的开发语言不同,因此ROS 的开发语言独立,支持C++,Python 等多种开发语言。
因此,除了官方提供的功能包之外,ROS 还聚合了全世界开发者实现的大量开源功能包,如思岚科技(SLAMTEC)就发布了针对其自主研发的激光雷达RPLIDAR 的ROS 功能包rplidar_ros。
这些开源功能包与ROS 一起构成了强大的开源生态环境。
ROS 的系统结构设计也颇有特色,ROS 运行时是由多个松耦合的进程组成,每个进程ROS 称之为节点(Node),所有节点可以运行在一个处理器上,也可以分布式运行在多个处理器上。
在实际使用时,这种松耦合的结构设计可以让开发者根据机器人所需功能灵活添加各个功能模块。
1理论分析1.1控制电机转动电机的控制我们分为两部分,一部分为电机转动方向的控制,另一个为电机转速的控制。
电机转动的方向我们用两个MCU 引脚来控制,假如PIN_A=1,PIN_B=0 时,电机正转;PIN_A=0,PIN_B=1 时,电机反转;PIN_A=0,PIN_B=0 时,电机停止。
电机速度的控制则需要一个PWM 输出引脚,我们通过控制输出不同的PWM 值来控制电机转动的速度。
1.2PID 控制如果我们想控制小车以一米每秒的速度做直线运动,但由于地面的阻力的影响,会造成左右轮速度与我们想控制的速度不同,所以不会沿直线运动,这时我们就需要加入PID 控制,PID 控制的思想就是我实时的把轮子真正的速度采集回来和控制的速度对比,差则补,多则减。
这样基本就可以实现理想控制。
针对该小车的PID 算法如附录A 所示。
1.3小车转弯控制图1 小车转弯控制计算分析一般我们要是想控制小车以多少的速度前进或者后退,我们只需要PID 控制两个轮子的速度一致就可以基本做到。
但如果要想控制小车以多少的角速度转弯,我们需要做一定的计算,如图1 所示。
1.4参数测量与计算编码器用于计算轮子的移动距离。
有两个问题需要解决:(1)高精度编码器太敏感,稍微抖动,会产生大量的不准确的值;(2)计数器的溢出。
可以根据实际小车的尺寸算出所需数据。
小车的各项参数如下:前后轮轴距2K=168 mm;左右轮距离2L=266 mm;车轮直径r=130 mm;电动机减速比1:30。
假设小车转向的角速度ω 为5 rad/s,转向半径R 为100 mm。
由上面的公式便可得出各个轮子的转速:n1=n3=18.3 m/s;n2=n4=116.1 m/s。
1.5ROS 平台与底盘通信协议[5](1)ROS 底盘串口ROS 平台与小车底盘的通信一般是通过串口或者CAN 总线。
我这里采用的是串口,以下为我自定义的通信数据格式。
1)底盘串口部分串口接收:小车左右轮速度,单位:mm/s(所有数据都为float 型,float 型占4 字节),10 字节:[右轮速度4 字节][左轮速度4 字节][结束符"\r\n"2 字节]。
串口发送:里程计x, y 坐标、线速度、角速度和方向角,单位依次为:mm, mm, mm/s, rad/s, rad(所有数据都为float 型,float 型占4 字节),21 字节:[x 坐标4 字节][y 坐标4 字节][方向角4 字节][线速度4 字节][角速度4 字节][结束符"\n"1 字节]。
2)ROS 平台串口节点部分写入串口:左右轮速度,单位为mm/s,10 字节,[右轮速度4字节][左轮速度4字节][结束符"\r\n"2字节]。
读取串口:小车x、y 坐标,方向角,线速度,角速度,单位依次为:mm,mm,rad,mm/s,rad/s,21 字节:[X坐标4字节][Y坐标4字节][方向角4字节][线速度4字节][角速度4字节][结束符"\n"1字节]。
2运动规划仿真2.1属性配置用moveit_assistant_setup 对机器人进行属性配置,如图 2 所示。
图 2 Moveit 属性设置2.2关节运动仿真通过moveit 成功用Rviz 进行了机器人关节运动仿真、整体运动仿真,如图3-图6 所示。
图3 urdf 模型关键运动仿真图4 Rviz 运动规划图5 Rviz 呈现小车图6 Rviz 呈现运动轨迹2.3运动仿真通过Rviz 对机器人模块进行运动仿真(下图为Linux 命令代码操作),如图8 所示。
图8 命令直接仿真机器人运动编写.launch 文件(c++编写)存放在package 包内的launch 文件(file)中,在Linux 命令框中用roslaunch 代码读取.launch 文件(文件中有机器人运动规划代码),如图9 所示。
图9 通过launch 文件编写代码对机器人进行复杂运动仿真用apt-get 在ROS 官网上下载摇杆包,通过摇杆仿真控制机器人运动,如图10 所示。
图10 通过摇杆控制规划运动路线2.4控制模拟右边命令框Arbotix Controller 是模拟摇杆控制器,系统通过采集摇杆节点输入数据想机器人节点发送topic 消息,并用rosrun 运行rqt_graph 弹出如下界面,对节点间的topic 话题进行可视化分析,如图11 所示。
图11 可视化节点消息图分析用marker 进行第三方控制,控制图如下,如图12、图13 所示。
图12 第三方控制为图中红色部分(在rqt_graph 上的呈现)图13 Rviz 下用控制完成圆路径以上是前期准备中的一部分,分别为环境搭建与机器人属性设置、运动规划模拟、与Arduino 开发板实际对接应用、可视化界面呈现与分析、节点话题可视化分析。
3结果分析以上仿真逐步实现从路径控制到小车的摇杆控制。
通过模拟分析得到了机器人运动现象,及相应的控制方法,为后续硬件的搭建与功能实现提供了参考。
由上述仿真可知,在ROS 平台相应仿真软件的帮助下,机器人的运动控制大幅度简单化,根据面向服务的思想,ROS 将硬件控制方式抽象成了话题订阅,实现了底层硬件和规划路径功能块的Service,本项目要做的是在两个模块中间协调通讯。
所以此项目将会把机器人设计成为两个板块,上位机树莓派通过ROS 的通讯协议接收下位机Arduino 接收的摄像头等传感器数据,并进行SLAM[4] 与基于PID 算法的路径规划的运算预处理,再将预处理数据结果通过ROS 通信协议返还给下位机Arduino 进行数据结果解析并对包括舵机转速、摄像头朝向等外部控制参数进行直接操作,最终在运动控制进行直接体现。
设计如图14 所示。
图14 移动机器人系统设计4总结针对当前研究室内环境,并同时实现定位与地图构建( SLAM)[3]功能的移动机器人成本高等问题,提出了一种低成本的开源移动机器人控制系统方案。
以控制芯片Arduino[1] 为基础,将开源机器人操作系统(ROS)移植到开源嵌入式系统当中,设计了基于ROS 的分布式上位机控制软件和实时操作系统的下位机程序,完成了移动机器人控制系统的搭建,实现了移动机器人的分布式控制。
移动机器人所使用软硬件均开源,成本低、性能高、可扩展性好。
研究结果表明,该控制系统具有较好的稳定性和实时性。
对该类机器人的开发与实际应用提供了一个新的思路与方法。
附录APID 算法——diff_controller.h 源码typedef struct {double TargetTicksPerFrame; // target speed in ticks per frame long Encoder; // encoder countlong PrevEnc; // last encoder countint PrevInput; // last inputint ITerm; //integrated termlong output; // last motor setting}SetPointInfo;SetPointInfo leftPID, rightPID;int Kp = 20;int Kd = 12;int Ki = 0;int Ko = 50;unsigned char moving = 0; // is the base in motion?void resetPID(){leftPID.TargetTicksPerFrame = 0.0;leftPID.Encoder = readEncoder(LEFT);leftPID.PrevEnc = leftPID.Encoder;leftPID.output = 0;leftPID.PrevInput = 0;leftPID.ITerm = 0;rightPID.TargetTicksPerFrame = 0.0;rightPID.Encoder = readEncoder(RIGHT);rightPID.PrevEnc = rightPID.Encoder;rightPID.output = 0;rightPID.PrevInput = 0;rightPID.ITerm = 0;}void doPID(SetPointInfo * p){ long Perror;long output;int input;input = p->Encoder - p->PrevEnc;Perror = p->TargetTicksPerFrame - input;output = (Kp * Perror - Kd * (input - p->PrevInput) + p->ITerm) / Ko; p->PrevEnc = p->Encoder;output += p->output;if (output >= MAX_PWM)output = MAX_PWM;else if (output <= -MAX_PWM)output = -MAX_PWM;elsep->ITerm += Ki * Perror;p->output = output;p->PrevInput = input;}void updatePID() {leftPID.Encoder = readEncoder(LEFT);rightPID.Encoder = readEncoder(RIGHT);if (!moving){if (leftPID.PrevInput != 0 || rightPID.PrevInput != 0) resetPID();return;}doPID(&rightPID);doPID(&leftPID);setMotorSpeeds(leftPID.output, rightPID.output);}long readPidIn(int i){ long pidin=0;if (i == LEFT){pidin = leftPID.PrevInput;}else {pidin = rightPID.PrevInput;}return pidin;}long readPidOut(int i){ long pidout=0;if (i == LEFT){pidout = leftPID.output;}else {pidout = rightPID.output;}return pidout;}附录BROS 的C++库——RoscppROS 系统接口相机驱动(1)camera_driversStreaming Camera NodesThis API is for cameras that produce a continuous stream of images(原文)获取与处理Kinetic 等其他图像获取设备的数据流Polled Camera NodesThis API is for cameras that produce an image only when polled. There may be multiple clients, each with their own response_namespace. These topics are only published in response to the request_image service. The polled_camera package provides support for implementing this API.(原文)对每一个相机进行轮询等操作(2)common_msgs(消息传递API)负责对整个系统内部不同部分相互传递消息(通信)的API(3)laser_drivers激光测距系统API(4)driver_common其他驱动程序和常用的驱动程序工具类(5)filters为系统内的数据过滤,官方提供的过滤器接口以及实现(6)laser_pipeline将激光传感器数据转为三维数据(7)image_commonROS 系统中对于图像处理的组件(8)image_pipelineROS 中的图片处理Pipeline,用于处理图像信息(如将相机获取到的数据进行处理并输出成OpenCV 可以处理的数据)(9)ision_opencvROS 与OpenCV 的接口,提供实时图像的OpenCV 编程(10)tfROS 中Transform Configuration(变换配置)相关的接口和组件(11)tf_conversionstf 数据类型的转换接口和组件(12)actionlib为ROS 系统中的Action Server 和Action Client 两个模块提供接口和工具。