|
【R325】小黑仿生轮腿机器人
作者:机器谱
本体说明 运动控制 超声避障 机器视觉 SLAM导航 |
1. 机器人整体描述
小黑仿生轮腿机器人是一款全向仿生轮腿,具备麦克纳姆轮底盘的运动特性的同时,还具备了部分四足仿生机器人的运动特性。通过4个麦克纳姆轮和腿部动作的配合,可以在运动中改变机身的姿态,适应不同的作业环境。
小黑仿生轮腿机器人的肩部安装了8个超声波传感器,还安装了激光雷达、双目摄像头和屏幕,可以用于更复杂的智能控制。
本体说明
2. 结构说明
轮腿本体结构为模块化结构设计,包含悬挂模块、腿模块、轮模块等。其中悬挂模块可以让机器人的轮子有更好的着地性,防止悬空。
肩膀位置的悬架上下板之间,安装了8个超声波传感器。
结构各部分说明:
零件包含机加工钣金零件、五金零件、3D打印零件,以及弹簧、同步皮带等。BOM及加工文件可在本文末尾下载。
3. 电子硬件
这款轮腿机器人主要的电子硬件包含一个控制机箱(机箱内含Arduino mega2560控制板、专用扩展板、电池等,机箱外部提供各种开关按钮和USB等接口)、树莓派4B、激光雷达、双目摄像头、显示屏、键盘、鼠标及相关的连接线。
我们把装有摄像头的那一端规定为轮腿的前端,下面是关于舵机的接线说明。
4个大标准舵机(模拟舵机)用于腿的摆动,4个总线舵机通过同步皮带带动麦克纳姆轮。
扩展板电路图如下:
大扩展板,直接堆叠在mega2560上
小扩展板1
堆叠在大扩展板上,含2个总线舵机接口、2个舵机接口、4个超声波传感器接口。
小扩展板2
含2个总线舵机接口、2个舵机接口、4个超声波传感器接口
小扩展板3(含6个传感器接口、2个串口、2个总线舵机接口、1个IIC接口、1个舵机接口)
扩展板PCB文件可以在文末下载。
轮腿机箱右侧常用接口:
其中各个接口的含义如下图所示:
机箱连接及开机视频:
4. BOM
名称 | 数量 | 规格 |
大臂输出头 | 4 | 6061铝氧化黑 |
电机壳1 | 4 | 6061铝氧化黑 |
电机壳2 | 4 | 6061铝氧化黑 |
舵机输出轴 | 4 | 6061铝氧化黑 |
机械臂 | 8 | 6061铝氧化黑 |
机械臂挡片 | 24 | 6061铝氧化黑 |
轮轴 | 4 | 304不锈钢 |
皮带轮1 | 8 | 6061铝氧化黑 |
皮带轮4 | 4 | 6061铝氧化黑 |
皮带轮5 | 4 | 6061铝氧化黑 |
皮带轮挡片 | 28 | 6061铝氧化黑 |
皮带轮挡片支架 | 8 | 6061铝氧化黑 |
皮带轮支架柱 | 4 | 6061铝氧化黑 |
25齿轮 | 4 | 铜 |
44齿轮 | 4 | 铜 |
车架 | 1 | 6061铝氧化黑 |
后支架板 | 1 | 6061铝氧化黑 |
前支架板 | 1 | 6061铝氧化黑 |
主控侧板 | 1 | 6061铝氧化黑 |
主控底板 | 1 | 6061铝氧化黑 |
主控顶板 | 1 | 6061铝氧化黑 |
主控后板 | 1 | 6061铝氧化黑 |
主控前板 | 1 | 6061铝氧化黑 |
乐视双目支架 | 1 | 亚克力黑色5mm |
雷达小板外壳1 | 1 | 进口高硬度尼龙_3D打印 |
雷达小板外壳2 | 1 | 进口高硬度尼龙_3D打印 |
超声波外壳1 | 4 | 进口高硬度尼龙_3D打印 |
超声波外壳2 | 4 | 进口高硬度尼龙_3D打印 |
电池仓 | 1 | 进口高硬度尼龙_3D打印 |
轮腿扩展版 | 1 | PCB |
轮腿连接板1 | 1 | PCB |
轮腿连接板2 | 1 | PCB |
轮腿连接板3 | 1 | PCB |
麦克纳姆轮 | 4 | 型号14144 |
皮带2 | 8 | 橡胶5M,310-5M |
六角铜柱15 | 4 | M3*15双通 |
总线舵机 | 4 | 串行总线舵机,送调试板 |
大扭力数字高压舵机 | 4 | |
轴承6701zz | 36 | 6701-zz(12*18*4) |
轴承MR85zz | 8 | MR85zz(5*8*2.5) |
舵机输出头 | 8 | |
M204黑色沉头螺丝 | 1 | M2*4 |
扭簧 | 8 | |
M210黑色沉头螺丝 | 1 | M2*10 |
树莓派4B | 1 | 内存4G |
32G内存卡 | 1 | |
树莓派显示屏 | 1 | 带支架 |
超声波模组 | 4 | 含PCB加工 |
Arduino Mega2560主控板 | 1 | |
2560主控板数据线 | 1 | |
11.1V动力电池 | 1 | |
杉川激光雷达 | 1 | 含数据线和转接板 |
乐视深度摄像头 | 1 | 含底座 |
弯头Type-c线(双弯头) | 1 | 0.25m |
直通HDMI航空头 | 1 | HDMI新款直通 |
D型ZUSB-3.0直通母座 | 1 | D型ZUSB-3.0直通母座 |
环形12V自锁开关 | 1 | 12V(自锁式)、22mm、环形+电源灯绿色带插座 |
电源适配器 | 1 | DC5.5mm接口,12V10A |
5V6A稳压模块 | 1 | 5V6A |
micro-HDMI线 | 1 | D2-A1 0.15m |
双公头USB | 1 | |
DC电源插座插孔 | 1 | |
双头JTAG排线30P | 1 | |
双头JTAG排线16P | 2 | |
动力电池电源线 | 1 | |
蓝牙键鼠套装 | 1 | |
USBhub3.0 | 1 | |
探索者4芯输入排线 | 8 | |
M3黑色沉头螺丝6mm | 100 | |
M3黑色沉头螺丝8mm | 100 | |
M3黑色沉头螺丝10mm | 100 | |
六角铜螺柱50 | 10 | M3*50(10粒) |
六角铜螺柱20 | 10 | M3*20(10粒) |
压簧50 | 4 | 1.0*8*50 |
5. 资料清单
序号 | 内容 |
1 | R325-轮腿驱动及控制-样机3D文件 |
2 | R325-轮腿-生产加工文件 |
【整体打包】-【R325】小黑仿生轮腿机器人-本体说明-资料附件.zip | 11.43MB | 下载12次 | 下载 |
运动控制
1. 运动功能描述
小黑仿生轮腿机器人是一款全向仿生轮腿,具备麦克纳姆轮底盘的运动特性的同时,还具备了部分四足仿生机器人的运动特性。通过4个麦克纳姆轮和腿部动作的配合,可以在运动中改变机身的姿态,适应不同的作业环境。
2. 运动功能的实现
本示例将提供轮腿的基本运动,包括前进、后退、左平移、右平移、左转、右转及轮腿变形运动的参考程序。
编程环境:Arduino 1.8.19
2.1 轮腿基本运动
实现思路:轮腿可以前进、后退、左平移、右平移、左转、右转。
例程(Base_Experiment\wheelLegDrive\wheelLegDrive.ino)
/*------------------------------------------------------------------------------------ 版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved. Distributed under MIT license.See file LICENSE for detail or copy at https://opensource.org/licenses/MIT by 机器谱 2023-02-28 https://www.robotway.com/ ------------------------------*/ /* * 功能:轮腿驱动 * * 车身位置及传感器\电机接线: * * Y * | * | * | * | 【车身左侧】 * | t:22 t:47 * | e:24 e:45 * | 舵机[servoPin:26] t:25 A - - - - - - - - - - - - - - - - - -Y: t:44 舵机[servoPin:43] * | e:23 | | e:46 * |【车尾】 | | 【车头】 * | t:31 | | t:40 * | 舵机[servoPin:27] e:29 Z - - - - - - - - - - - - - - - - - -X: e:38 舵机[servoPin:42] * | t:28 t:39 * | e:30 e:41 * | 【车身右侧】 * | * 0----------------------------------------------------------------------------------------------------------X * ////////////////// */ //#include <SoftwareSerial.h> #include<Servo.h> //#include<ServoTimer2.h> #define StepTest 20 #define BaudRate 115200 #define StepTestMultiple 1 #define BriefDelayTimes 10 #define ActionDelayTimes 1500 #define CarActionDelayTime 600 #define mySerial Serial1 #define set_pwm_now 2500 #define set_pwm_nows 1500 bool Ultrasonic_flags[8]={}; long GetUltrasonicDatas[8]={}; double ActualSteps = StepTest*StepTestMultiple; enum{FORWARD=1,BACK,LEFTROAD,RIGHTROAD,AUTO_MOVE}; float wheel_Speed[4]={0,0,0,0}; float current_vx = 0,current_vy = 0,current_va = 0; //SoftwareSerial mySerial(51, 9); void setup() { delay(1000); mySerial.begin(115200); Serial.begin(BaudRate);//set Baud rate init_Servo();delay(300); init_Ultrasonic(); XYSetVel(0.0,0.0, 0.0);delay(300); moveTest(); } void loop() { //moveTest(); //Get_ultrasonic_sensor_data(); } void control_single_motor(int speed_single,int pwm) { char cmd_return[200]; sprintf(cmd_return, "{#%03dP%04dT%04d!}",0,pwm,1); mySerial.print(cmd_return); } void moveTest(){ XYSetVel(0.05, 0.0, 0.0);delay(2000); //forward 前进 XYSetVel(0.0,0.0, 0.0);delay(2000);//停止 XYSetVel(-0.05,0.0,0.0);delay(2000); //back 后退 XYSetVel(0.0,0.0, 0.0);delay(2000); XYSetVel(0.0,0.0,-0.20);delay(2000); //left 左转 XYSetVel(0.0,0.0, 0.0);delay(2000); XYSetVel(0.0 ,0.0,0.20 );delay(2000); //right 右转 XYSetVel(0.0,0.0, 0.0);delay(2000); XYSetVel( 0.0, -0.05, 0.0);delay(2000);//Left translation 左平移 XYSetVel( 0.0, 0.05, 0.0);delay(2000);//right translation 右平移 XYSetVel(0.0,0.0, 0.0);delay(2000); } |
/*------------------------------------------------------------------------------------ 版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved. Distributed under MIT license.See file LICENSE for detail or copy at https://opensource.org/licenses/MIT by 机器谱 2023-02-28 https://www.robotway.com/ ------------------------------*/ /* * 功能:轮腿变形 * * * 车身位置及传感器\电机接线: * * Y * | * | * | * | 【车身左侧】 * | t:22 t:47 * | e:24 e:45 * | 舵机[servoPin:26] t:25 A - - - - - - - - - - - - - - - - - -Y: t:44 舵机[servoPin:43] * | e:23 | | e:46 * |【车尾】 | | 【车头】 * | t:31 | | t:40 * | 舵机[servoPin:27] e:29 Z - - - - - - - - - - - - - - - - - -X: e:38 舵机[servoPin:42] * | t:28 t:39 * | e:30 e:41 * | 【车身右侧】 * | * 0----------------------------------------------------------------------------------------------------------X * ////////////////// */ #include<Servo.h> #define StepTest 20 #define BaudRate 115200 #define StepTestMultiple 1 #define BriefDelayTimes 10 #define ActionDelayTimes 1500 #define CarActionDelayTime 600 #define mySerial Serial1 #define set_pwm_now 2500 #define set_pwm_nows 1500 bool Ultrasonic_flags[8]={}; long GetUltrasonicDatas[8]={}; double ActualSteps = StepTest*StepTestMultiple; enum{FORWARD=1,BACK,LEFTROAD,RIGHTROAD,AUTO_MOVE}; float wheel_Speed[4]={0,0,0,0}; float current_vx = 0,current_vy = 0,current_va = 0; void setup() { delay(3000); mySerial.begin(115200); Serial.begin(BaudRate);//set Baud rate init_Servo();delay(2300); init_Ultrasonic(); XYSetVel(0.0,0.0, 0.0);delay(2300); Dog_Dance(); } void loop() { } |
2.2 轮腿变形运动
实现思路:通过控制轮腿的舵机,来实现轮腿变形的效果。
例程(Base_Experiment\Wheel_leg_deformation\Wheel_leg_deformation.ino)
3. 资料清单
序号 | 内容 |
1 | R325-轮腿驱动及控制-例程源代码 |
【整体打包】-【R325】小黑仿生轮腿机器人-运动控制-资料附件.zip | 15.2KB | 下载4次 | 下载 |
超声避障
1. 功能描述
在轮腿上装8个 超声测距传感器 ,本文示例将实现轮腿避障的效果。
2. 电路连接
轮腿的每个边角上装有2个超声测距传感器,共8个,超声测距传感器的PCB是重新设计的,如下图所示:
超声测距传感器的安装位置如下图所示:
3. 功能实现
编程环境:Arduino 1.8.19
参考例程(Base_Experiment\Control_IicServo_and_Servo),实现轮腿避障效果。下面是主程序Control_IicServo_and_Servo.ino:
/*------------------------------------------------------------------------------------ 版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved. Distributed under MIT license.See file LICENSE for detail or copy at https://opensource.org/licenses/MIT by 机器谱 2023-02-28 https://www.robotway.com/ ------------------------------*/ /* * 轮腿避障 * * 车身 位置及传感器\电机接线: * * Y * | * | * | * | 【车身左侧】 * | t:22 t:47 * | e:24 e:45 * | 舵机[servoPin:26] t:25 A - - - - - - - - - - - - - - - - - -Y: t:44 舵机[servoPin:43] * | e:23 | | e:46 * |【车尾】 | | 【车头】 * | t:31 | | t:40 * | 舵机[servoPin:27] e:29 Z - - - - - - - - - - - - - - - - - -X: e:38 舵机[servoPin:42] * | t:28 t:39 * | e:30 e:41 * | 【车身右侧】 * | * 0----------------------------------------------------------------------------------------- * ////////////////// */ //#include <SoftwareSerial.h> #include<Servo.h> //#include<ServoTimer2.h> #define StepTest 20 #define BaudRate 115200 #define StepTestMultiple 1 #define BriefDelayTimes 10 #define ActionDelayTimes 1500 #define CarActionDelayTime 600 #define mySerial Serial1 #define set_pwm_now 2500 #define set_pwm_nows 1500 bool Ultrasonic_flags[8]={}; long GetUltrasonicDatas[8]={}; double ActualSteps = StepTest*StepTestMultiple; enum{FORWARD=1,BACK,LEFTROAD,RIGHTROAD,AUTO_MOVE}; float wheel_Speed[4]={0,0,0,0}; float current_vx = 0,current_vy = 0,current_va = 0; //SoftwareSerial mySerial(51, 9); void setup() { delay(500); mySerial.begin(115200); Serial.begin(BaudRate);//set Baud rate init_Servo();delay(300); init_Ultrasonic(); XYSetVel(0.0,0.0, 0.0);delay(300); moveTest(); Dog_Dance(); } void loop() {
Get_ultrasonic_sensor_data(); } void control_single_motor(int speed_single,int pwm) { char cmd_return[200]; sprintf(cmd_return, "{#%03dP%04dT%04d!}",0,pwm,1); mySerial.print(cmd_return); } void moveTest(){ XYSetVel(0.05, 0.0, 0.0);delay(2000); //forward 前进 XYSetVel(0.0,0.0, 0.0);delay(2000);//停止 } |
4. 资料清单
序号 | 内容 |
1 | R325-轮腿避障-例程源代码 |
【整体打包】-【R325】仿生轮腿-避障-资料附件.zip | 7.9KB | 下载3次 | 下载 |
机器视觉
1. 功能描述
机器视觉系统是通过机器视觉产品(即图像摄取装置,分CMOS和CCD两种)将被摄取目标转换成图像信号,传送给专用的图像处理系统,得到被摄目标的形态信息,根据像素分布和亮度、颜色等信息,转变成数字化信号;图像系统对这些信号进行各种运算来抽取目标的特征,进而根据判别的结果来控制现场的设备动作。
本文将结合机器视觉基础,基于开源的轮腿机器人平台,进行形状识别(识别圆形)、颜色检测(红绿蓝)、颜色追踪的应用开发。
实现思路:利用摄像头采集图片信息识别圆形,在界面上显示出圆的圆心坐标。
操作步骤:
(1)如果您的机器人还没有配置好环境变量,那需要先把资料附件里的visual_experiment_ws文件夹拷贝到系统里,然后执行:
① 在visual_experiment_ws文件夹中的src文件夹同级别目录下,编译工作空间,并配置环境变量;
② 打开终端(Ctrl+Alt+T),输入roslaunch astra_camera astra.launch(见下图),等待程序的运行。
(2)如果您的机器人已经配置好了环境变量,或(1)中的操作已经完成,则执行:
① 打开第二个终端(Ctrl+Shift+T)输入命令:roslaunch shape_detection shape_detection_experiment.launch,等待界面的启动;
② 放置待识别的圆形图(请把物品放置在摄像头可以采集到的区域),就可以在界面上看到识别结果。下图是分别识别出红色圆形、绿色圆形轮廓,并显示识别出圆心的中心坐标x、y的值。
这个功能的python例程源码在visual_experiment_ws\src\shape_detection\scripts文件夹里, 文件名是shape_detection_victory.py,该程序的关键点是:先采集图像信息,再对图像信息进行处理,把识别信息显示在界面上,大家有兴趣可以阅读参考。
2.2 颜色检测(红绿蓝)
主要用到的器材:摄像头、红绿蓝三种物品(见下图)
实现思路:当把物品放置在摄像头前时,在界面上显示识别颜色的结果。
颜色识别算法的核心原理:
RGB和HSV彩色模型:
数字图像处理通常采用RGB(红、绿、蓝)和HSV(色调、饱和度、亮度)两种彩色模型,RGB虽然表示比较至直观,但R、G、B数值和色彩三属性并没有直接关系,模型通道并不能很好的反映出物体具体的颜色信息,而HSV模型更符合我们描述和解释颜色的方式,使用HSV的彩色描述会更加直观。
RGB和HSV的区别:
①. RGB模型
三维坐标:
RGB:三原色(Red, Green, Blue)
原点到白色顶点的中轴线是灰度线,r、g、b三分量相等,强度可以由三分量的向量表示。
用RGB来理解色彩、深浅、明暗变化:
色彩变化: 三个坐标轴RGB最大分量顶点与黄紫青YMC色顶点的连线
深浅变化:RGB顶点和CMY顶点到原点和白色顶点的中轴线的距离
明暗变化:中轴线的点的位置,到原点,就偏暗,到白色顶点就偏亮
②. HSV模型
倒锥形模型:
这个模型就是按色彩、深浅、明暗来描述的。
H是色彩
S是深浅, S = 0时,只有灰度
V是明暗,表示色彩的明亮程度,但与光强无直接联系,(意思是有一点点联系吧)。
③. RGB与HSV的联系
从上面的直观的理解,把RGB三维坐标的中轴线立起来,并扁化,就能形成HSV的锥形模型了。
但V与强度无直接关系,因为它只选取了RGB的一个最大分量。而RGB则能反映光照强度(或灰度)的变化。
v = max(r, g, b)
由RGB到HSV的转换:
④. HSV色彩范围
操作步骤:
(1)先把资料附件里的visual_experiment_ws文件夹拷贝到系统里,然后执行:
① 在visual_experiment_ws文件夹中的src文件夹同级别目录下,编译工作空间,并配置环境变量;
② 打开终端(Ctrl+Alt+T),输入roslaunch astra_camera astra.launch(见下图),等待程序的运行。
③ 打开第二个终端(Ctrl+Shift+T)输入命令:roslaunch color_detection color_detectioning.launch,等待程序的运行。
④ 界面启动后,放置物品(请把物品放置在摄像头可以采集到的区域),然后开始识别并在界面上显示识别结果。下面以蓝色物品为例,当摄像头识别到蓝色物品后,在界面显示结果(the color is blue)。
⑤ 试着去放置红色、绿色物品,分别识别出的结果如下面两幅图。当摄像头识别到红色物品后,在界面显示结果(the color is red);当摄像头识别到绿色物品后,在界面显示结果(the color is green)。
2.3 颜色追踪
主要用到的器材:本实验中需要用到的器材见下图,用红色的灭火器作为被追踪的物体。
实现思路:摄像头采集到红色物品后,通过串口通信来发布消息,轮腿订阅消息后进行相应的运动。
操作步骤:
①首先参考2.2中的步骤,实现颜色检测功能。
②打开资料中的
visual_experiment_ws\src\color_tracking\arduino_program\Color_Tracking_Arduino_Program文件夹,下载程序Color_Tracking_Arduino_Program.ino至轮腿机器人的mega2560主控板。
/*------------------------------------------------------------------------------------ 版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved. Distributed under MIT license.See file LICENSE for detail or copy at https://opensource.org/licenses/MIT by 机器谱 2023-03-01 https://www.robotway.com/ ------------------------------*/ /* * 颜色追踪下位机程序 */ #include <ros.h> #include <std_msgs/String.h> #include <Arduino.h> #include <stdio.h> #include <string.h> #define CTL_BAUDRATE 115200 //总线舵机波特率 #define mySerial Serial1 #define SerialBaudrate 57600 #define RGB_LED_NU MBERS 3 #define Bus_servo_Angle_inits 1500 #define ActionDelayTimes 1500 // #define wheel_speed_forward 0.07 //car forward speed #define wheel_speed_back -0.07 //car back speed #define wheel_speed_stop 0.0 //car stop speed #define wheel_speed_left 0.07 //car turnleft speed #define wheel_speed_right -0.07 //car turnright speed #define wheel_speed_left_translation -0.07 //speed of car left translation #define wheel_speed_right_translation 0.07 //speed of car right translation String receive_string="hello"; ros::NodeHandle nh; void messageCb( const std_msgs::String &toggle_msg){ receive_string=toggle_msg.data; } ros::Subscriber<std_msgs::String> sub("hahaha", &messageCb ); //std_msgs::String str_msg; //ros::Publisher chatter("chatter", &str_msg); enum{FORWARD=1,BACK,LEFT,RIGHT,LEFT_TRANSLATION,RIGHT_TRANSLATION,STOP}; //the movement state of the car void setup() { delay(1100); Serial.begin(SerialBaudrate); mySerial.begin(CTL_BAUDRATE); init_Servo(); nh.initNode(); nh.subscribe(sub); } void loop() { if( (receive_string.length())<5 && (receive_string.length())>15 ) { for(int i=0;i<1;i++){ break; } } else{ int SpacePosition[2] = {0,0}; int Data_one = 0; int Data_two = 0; int numbers_left=0 ,numbers_right=0; char num_left[32] = {}; char num_right[32] = {}; String x_data=""; String y_data=""; String z_data=""; String new_string = ""; SpacePosition[0] = receive_string.indexOf('-'); x_data = receive_string.substring(0,SpacePosition[0]); //if(x_data.length()>=4){break;} new_string = receive_string.substring(SpacePosition[0]+1); SpacePosition[1] = new_string.indexOf('+'); y_data = new_string.substring(0,SpacePosition[1]); z_data = new_string.substring(SpacePosition[1]+1); Data_one = x_data.toInt(); Data_two = y_data.toInt(); //if( (Data_one<=120) && (z_data =="state") ){Car_Move(LEFT_TRANSLATION);} if( (Data_one<=280) && (Data_one>=20)){Car_Move(LEFT_TRANSLATION);} else if ( (Data_one>=360) && (Data_one<=600) ){Car_Move(RIGHT_TRANSLATION);} else if( z_data == "forward" ){Car_Move(FORWARD);} else if( z_data == "back" ){Car_Move(BACK );} else {Car_Move(STOP);}
receive_string = ""; x_data=""; y_data=""; z_data=""; new_string=""; } nh.spinOnce(); delay(100); } |
③ 打开终端(Alt+ctrl+T),输入roslaunch astra_camera astra.launch 命令即可,见下图。
④ 打开第二个终端(shift+ctrl+T),输入roslaunch color_tracking camera_calibration.launch 命令,见下图。
⑤ 移动灭火器,观察轮腿跟随灭火器运动的效果。
注意1:请把灭火器放置在摄像头可采集到的区域内;
注意2:受硬件的影响,移动灭火器的速度建议稍微慢点,如可以先把灭火器移动到一个位置,观察轮腿追踪的效果。
我在可以在rviz界面里看到摄像头采集到红色目标的中心坐标及面积,供追踪使用(见下图);同时可以观察到轮腿进行追踪红色的灭火器,直到运动到靠近灭火器的地方。
这个功能的python例程源码在visual_experiment_ws\src\color_tracking\scripts文件夹里, 文件名是ros_arduino_translation_test.py,该程序的关键点是:识别红色区域并在界面上显示识别后的坐标及面积。大家有兴趣可以阅读参考。
3. 资料清单
序号 | 内容 |
1 | R325-轮腿机器人-机器视觉-例程源代码 |
【整体打包】-【R325】仿生轮腿-机器视觉-资料附件.zip | 27.02MB | 下载3次 | 下载 |
SLAM导航
1. 功能描述
本文将利用键盘控制轮腿运动完成slam建图,并能在已建好的地图里进行自主导航。slam导航可以拆分为三步:
第一步:能用键盘控制轮腿机器人运动;
第二步:基于实际场景,用键盘控制轮腿机器人进行slam建图;
第三步:基于已建好的地图,模拟实现slam导航。
2. 功能实现
操作系统:Ubuntu18.04系统,基于Debian GNU/Linux,支持x86、amd64(即x64)、ARM和ppc架构。
仿真系统:基于开源机器人操作系统ROS melodic和开源软件平台Arduino开发,上位机采用ROS melodic,基于Rviz完成全向移动轮腿slam导
航运动规划,采用gazebo完成全向移动轮腿物理运动仿真;下位机采用Arduino实现对全向移动轮腿运动的控制。
编程环境:Arduino 1.8.19
2.1 键盘控制轮腿运动
(1)实现思路:按下键盘上指定的键时,可以实现轮腿前进、后退、转向、平移;还可以灵活的设置轮腿的角速度、线速度来调整轮腿的运动。下
面是规划的控制轮腿的键盘命令(见下表)。可以先熟悉一下,后续在控制轮腿机器人时会用到。
分类 | 运动指令 | |
键盘快捷键 | 指令含义 | |
基本运动 | i | 前进 |
, | 后退 | |
j | 左转 | |
l | 右转 | |
平移 | J | 左平移 |
L | 右平移 | |
调整角速度与线速度 | q | 增大轮腿最大速度的10%(包含角速度与线速度) |
z | 减小轮腿最大速度的10%(包含角速度与线速度) | |
调整线速度 | w | 仅仅增大轮腿线速度的10% |
x | 仅仅减小轮腿线速度的10% | |
调整角速度 | e | 仅仅增大轮腿角速度的10% |
c | 仅仅减小轮腿角速度的10% | |
除了上面的按键其他按键(如:k) | 停止 | |
Ctrl+c | 程序结束 |
/*------------------------------------------------------------------------------------ 版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved. Distributed under MIT license.See file LICENSE for detail or copy at https://opensource.org/licenses/MIT by 机器谱 2023-03-02 https://www.robotway.com/ ------------------------------*/ /* * 上位机(ros)与下位机(arduino)消息发送与接收。 * * * 车身位置及传感器\电机接线: * * Y * | * | * | * | 【车身左侧】 * | t:A10 t:A9 * | e:A11 e:A8 * | 舵机[servoPin:26] t:A14 A - - - - - - - - - - - - - - - - - -Y: t:A5 舵机[servoPin:43] * | e:A15 | | e:A4 * | | | 【车头】 * | t:A13 | | t:A6 * | 舵机[servoPin:27] e:A12 Z - - - - - - - - - - - - - - - - - -X: e:A7 舵机[servoPin:42] * | t:32 t:46 * | e:31 e:45 * | 【车身右侧】 * | * 0----------------------------------------------------------------------------------------------------------X */ //DUE控制版需要启用USE_USBON或USE_NATIVE_USB,UNO不需要 //#define USE_USBCON //PAOGRAMMING PORT //#define USE_NATIVE_USB //NATIVE USB PORT #define ActionDelayTimes 1500 #define set_delay 1000 //#include <SoftwareSerial.h> #include <ros.h> #include <ros/time.h> //#include<ServoTimer2.h> #include<Servo.h> #include <geometry_msgs/Vector3.h> #define mySerial Serial1 ros::NodeHandle nh; void XYRun(double vx, double vy, double w); void messageCb( const geometry_msgs::Vector3& vel_cmd) {XYSetVel(vel_cmd.x, vel_cmd.y, vel_cmd.z);} ros::Subscriber<geometry_msgs::Vector3> vel_cmd_sub("vel_cmd", &messageCb ); geometry_msgs::Vector3 pose_message; ros::Publisher pose_feedback_pub("pose_feedback",&pose_message); geometry_msgs::Vector3 vel_message; ros::Publisher vel_feedback_pub("vel_feedback",&vel_message); //ServoTimer2 myServo[4];//statement servo Servo myServo[4]; const int kMessagePubRate = 5; unsigned long message_pub_time = 0; const int kReadMotorDeltaT = 5; unsigned long position_read_time = 0; float current_x = 0,current_y = 0,current_a = 0; float current_vx = 0,current_vy = 0,current_va = 0; float wheel_Speed[4]={0,0,0,0}; char cmd_return[200]; float sudu = 0.87; //SoftwareSerial mySerial(51, 9); void setup() { delay(1000); mySerial.begin(115200); init_Servo();delay(300); //Servo_Action_Test();delay(1500); nh.initNode(); nh.subscribe(vel_cmd_sub); nh.advertise(pose_feedback_pub); nh.advertise(vel_feedback_pub); XYSetVel(0.0,0.0,0.0); moveTest(); position_read_time = millis(); message_pub_time = millis(); } void loop() { if(millis()>position_read_time) { XYread(); position_read_time+=kReadMotorDeltaT; }
if(millis()>message_pub_time) { pose_message.x = current_x; pose_message.y = current_y; pose_message.z = current_a; vel_message.x = current_vx; vel_message.y = current_vy; vel_message.z = current_va; pose_feedback_pub.publish(&pose_message); vel_feedback_pub.publish(&vel_message); message_pub_time+=1000.0/kMessagePubRate; } nh.spinOnce(); } void moveTest(){ XYSetVel(0.05, 0.0, 0.0);delay(set_delay); //forward 前进 XYSetVel(0.0,0.0, 0.0);delay(set_delay);//停止 XYSetVel(-0.05,0.0,0.0);delay(set_delay); //back 后退 XYSetVel(0.0,0.0, 0.0);delay(set_delay); // XYSetVel(0.0,0.0,-0.20);delay(set_delay); //left 左转 // XYSetVel(0.0,0.0, 0.0);delay(set_delay); // XYSetVel(0.0 ,0.0,0.20 );delay(set_delay); //right 右转 // XYSetVel(0.0,0.0, 0.0);delay(set_delay); // XYSetVel( 0.0, -0.05, 0.0);delay(set_delay);//Left translation 左平移 // XYSetVel( 0.0, 0.05, 0.0);delay(set_delay);//right translation 右平移 XYSetVel(0.0,0.0, 0.0);delay(set_delay); } |
(2)操作步骤:
① 打开参考例程文件夹(fourmacnum_car_ws\src\arduino_programming\Ros_Arduino_Translation_Programming),下载控制轮腿的程序
Ros_Arduino_Translation_Programming.ino:
② 启动雷达、键盘、rosserial程序包。打开终端,输入roslaunch robot_navigation_control robot.launch命令(见下图),等待程序的运行启动
界面。
终端
成功启动后,可以在终端看到轮腿的当前speed(线速度)为0.04,turn(角速度)为0.08。
注意:speed指的是线速度的大小(包含方向),turn指的是角速度的大小(包含方向)。
启动后的界面(见下图):
③ 尝试按下键盘命令,控制轮腿的运动。 (注意:一、请先保证终端是激活状态,见上图;二是按键盘时,稍微有点间隔,这样好给轮腿转动的
时间)。
假如现在希望先增加轮腿的最大速度,再降低轮腿的最大速度,则分别按下键盘上q、z命令,可以观察到终端的结果(见下图)。
更多命令可自行尝试。
2.2 轮腿同步定位与建图-SLAM
(1)实现思路:利用Gmapping算法对轮腿所在的未知环境进行建立地图、同步定位、最后保存此地图。此地图可供后续轮腿导航使用。
Gmapping算法是目前基于激光雷达和里程计方案里面比较可靠和成熟的一个算法, 它基于粒子滤波,采用RBPF的方
法,效果稳定。本次轮腿机器人slam建图采用的是gmapping_slam包。下面介绍Gmapping SLAM计算图。Gmapping的作
用是根据激光雷达和里程计(Odometry)的信息,对环境地图进行构建,并且对自身状态进行估计。因此它得输入应当包括
激光雷达和里程计的数据,而输出应当有自身位置和地图。下面我们从计算图(消息的流向)的角度来看看gmapping算法在
实际运行中的结构:
位于中心的是我们运行的slam_gmapping节点,这个节点负责整个gmapping SLAM的工作。它的输入需要有两个:
输入
/tf以及/tf_static:坐标变换,类型为第一代的tf/tfMessage或第二代的 tf2_msgs/TFMessage 其中一定得提供的有两个tf,一个是base_frame 与 laser_frame 之间的tf,即机器人底盘和激光雷达之间的变换;一个是base_frame 与 odom_frame之间的tf,即底盘和里程计原点之间的坐标变换。odom_frame可以理解为里程计原点所在的坐标系。
/scan:激光雷达数据,类型为sensor_msgs/LaserScan
/scan很好理解,Gmapping SLAM所必须的激光雷达数据,而/tf 是一个比较容易忽 视的细节。尽管/tf 这个Topic听起来很简单,但它维护了整个ROS三维世界里的转换关系,而 slam_gmapping要从中读取的数据是base_frame 与 laser_frame 之间的tf,只有这样才能够把周围障碍物变换到机器人坐标系下,更重要的是base_frame 与 odom_frame之间的tf,这个tf 反映了里程计(电机的光电码盘、视觉里程计、IMU)的监测数据,也就是机器人里程计测得走了多少距离,它会把这段变换发布到odom_frame 和 laser_frame 92之间。因此slam_gmapping 会从/tf 中获得机器人里程计的数据。
输出
/tf:主要是输出 map_frame 和 odom_frame 之间的变换
/slam_gmapping/entropy:std_msgs/Float64 类型,反映了机器人位姿估计的分 散程度
/map:slam_gmapping 建立的地图
/map_metadata:地图的相关信息
输出的/tf 里又一个很重要的信息,就是map_frame和odom_frame之间的变换,这 其实就是对机器人的定位。通过连通map_frame和odom_frame,这样map_frame与 base_frame 甚至与 laser_frame 都连通了。这样便实现了机器人在地图上的定位。
(2)操作步骤:
① 启动雷达、键盘、rosserial。打开终端并输入命令:roslaunch robot_navigation_control robot_car.launch(见下图)。
② 启动构建地图服务。重新打开新终端并输入:roslaunch four_macnum_slam four_macnum_slam.launch(见下图)。
界面启动后,在rviz中选择“map”,可以在可视化界面看到有地图出现;
下面根据实际环境进行建图:按下键盘相关指令(键盘指令请参考上面2.1内容)来控制轮腿在场地内运行,直至在Rviz内可以看到构建地图的轮
廓,如下图所示(注意实际地图环境不同,出现的轮廓不同)。
轮腿在未知环境中建立地图
③ 为了后续在已知环境中运行轮腿,需把此次建立的地图进行保存。需要先进入保存地图的文件夹,然后给地图命名保存即可(见下图)。
下面是以保存your_map_name地图为例来介绍地图的保存过程:
重新打开新终端(ctrl+shift+t)并输入:cd fourmacnum_car_ws/src/four_macnum_navigation/maps
之后输入:rosrun map_server map_saver -f ./your_map_name
返回下图红色框的信息,代表成功保存地图。
查看生成的地图文件:
上面我们用map_server来保存地图。这里我们来简单了解和查看一下刚才保存的地图文件(见下图)。其中map_server是一个和地图相关的功能包,它可以将已知地图发布出来,供导航和其他功能使用,也可以保存SLAM建立的地图。
地图文件,通常为pgm格式;
地图的描述文件,通常为yaml格式。
打开your_map_name.pgm,见下图:
your_map_name.yaml ,各个参数见下图。
其中占据的概率 occ = (255-color_avg)/255.0,color_avg为RGB三个通道的平均值。
2.3 轮腿导航—Navigation
(1)实现思路:加载上述2.2建好的地图,设置轮腿机器人的初始位置和方向,设定目标位置及方向,轮腿就可以实现导航效果。
Navigation与机器人底盘关系:ROS的二维导航功能包,简单来说,就是根据输入的里程计等传感器的信息流和机器人的全局位置,通过导航算
法,计算得出安全可靠的机器人速度控制指令。但是如何在特定的机器人上实现导航功能包的功能,却是一件较为
复杂的工程,作为导航功能包使用的必要先决条件,机器人必须运行ROS,发布tf变换树,并发布使用ROS消息类
型的传感器数据。同时为了让机器人更好的完成导航任务,开发者还要根据机器人的外形尺寸和性能, 配置导航功
能包的一些参数。
在ROS中进行导航需要使用到的三个包是:
① move_base:根据参照的消息进行路径规划,使移动机器人到达指定的位置;
② gmapping:根据激光数据(或者深度数据模拟的激光数据)建立地图;
③ amcl:根据已经有的地图进行定位。
(2)操作步骤:
① 将创建的地图应用到导航程序中。
这里我们需要修改four_macnum_navigation.launch文件,把上述2.2的zhanhui_mapping_test.yaml 添加到此launch文件中。
步骤如下:
打开终端并输入:cd fourmacnum_car_ws/src/four_macnum_navigation/launch
之后再输入:gedit four_macnum_navigation.launch
② 启动雷达、键盘、rosserial。在该终端继续输入:roslaunch robot_navigation_control robot_car.launch。
③打开新终端并输入:roslaunch four_macnum_navigation four_macnum_navigation.launch(见下图)。
启动界面后,可以看到许多红色的箭头,代表轮腿的姿态估计还不准确。
④ 开始调整轮腿的姿态。使用2D Pose Estimate 标定轮腿位于地图中的初始位置及车头指向(见下图)。
⑤ 鼠标点击有roslaunch robot_navigation_control robot_car.launch的终端后,尝试按下键盘命令控制轮腿运动(键盘命令请参考上面2.1内容),最好尽可能多的消除地图中的箭头(这一步实际是确定轮腿在地图中的实际位置以及车头指向)。下面是多次按下键盘命令控制轮腿运动后,箭头逐渐减少的效果。
下图是最后调整完的轮腿姿态(即轮腿在地图中的实际位置以及车头指向)。
⑥ 尝试给定轮腿目标位置(使用2D Nav Goal),这里的目标位置包含了目标点及车头指向,在可视化界面点击且转动箭头防线,机器人会移动到指定点的位置。
3. 资料清单
序号 | 内容 |
1 | R325-slam导航-例程源代码 |
【整体打包】-【R325】小黑仿生轮腿机器人-slam导航-资料附件.zip | 7.82MB | 下载4次 | 下载 |