台车机器人2.0。第1部分。基于ROS的家用机器人的自主导航

该项目是基于其圈子中另一个知名项目linorobot(linorobot.org)构建的,它使用了简单的外行可以使用的组件。设定的目标:使用低成本组件实现机器人在家中的自主移动,评估用于所述目的的微型PC的性能,配置导航堆栈以在赫鲁晓夫的狭窄空间中移动。




固体中的组分列表如下:

  • 树莓pi 3b-2800 r .;
  • 激光雷达rplidar a1-7500羽;
  • 动力桥l298n -2pcs-400擦。;
  • 带A和B型编码器的轮对-2000 r。(210 rpm- 链接
  • teenzy 3.2-2100 r。;
  • imu 9250(9150或6050)-240页;
  • 10000mH-1500 r的移动电源。
  • 3个电池18650和固定器-600 p。
  • 降压转换器dc-dc c 5V至3.3V-20p。
  • 一块胶合板,镶木地板?擦。

总计:17160羽

*用arduino mega 2560(600 p。)代替teenzy可以降低成本,而用kinect v.1(1000 p。)代替激光雷达可以降低成本:



但是,应注意的是,第一种kinect的最小可见度(盲区)为0.5 m,在狭窄的条件下可能会对导航产生负面影响,而且体积很大。激光雷达的盲区小于0.2 m。Kinect v.2将不适合覆盆子3b(不具有USB 3.0)。Arduino mega的大小(和某些特性)不及teenzy,此外,您还必须对代码稍做修改。

通常,“设计”如下所示:





当然,这里没有美,但这并不是关于美的。

除了机器人本身之外,非常需要有一台外部PC,在其上将启动用于可视化机器人动作的图形化外壳(rviz,凉亭)。

机器人组装


它是在项目网站上详细绘出的- 链接,因此让我们关注引起困难的要点。首先,您需要考虑到轮对上的编码器由3.3V供电,并且当施加5V电压时,它会完全失效。

linorobot安装脚本已成功安装在ubuntu 16.04,ubuntu 18.04上。ROS版本:ROS动力学或ROS旋律。在树莓3b上,您必须首先创建一个交换文件。

主要的teenzy代码是这样的:

roscd linorobot/teensy/firmware/lib/config
nano lino_base_config.h

并使用以下命令将其倒入其中:

roscd linorobot/teensy/firmware
platformio run --target upload

上面的命令捆绑包将经常使用,因此将它们添加到别名是有意义的。

由于组装机器人的困难,从1298n到teenzy的连接触点的正确关联可能会很麻烦。尽管接线图非常清晰,但车轮仍可能表现不同,必须进行试验,在代码中选择正确的引脚分配。

就我而言,结果是这样的:

/// ENCODER PINS
#define MOTOR1_ENCODER_A 14
#define MOTOR1_ENCODER_B 15 

#define MOTOR2_ENCODER_A 11
#define MOTOR2_ENCODER_B 12 
//MOTOR PINS
#ifdef USE_L298_DRIVER
  #define MOTOR_DRIVER L298

  #define MOTOR1_PWM 21
  #define MOTOR1_IN_A 1
  #define MOTOR1_IN_B 20

  #define MOTOR2_PWM 5
  #define MOTOR2_IN_A 8
  #define MOTOR2_IN_B 6

第二点是规定机器人轮子的规格:

//define your robot' specs here
#define MAX_RPM 210               // motor's maximum RPM
#define COUNTS_PER_REV 1365       // wheel encoder's no of ticks per rev
#define WHEEL_DIAMETER 0.065       // wheel's diameter in meters
#define PWM_BITS 8                // PWM Resolution of the microcontroller
#define LR_WHEELS_DISTANCE 0.235  // distance between left and right wheels
#define FR_WHEELS_DISTANCE 0.30   // distance between front and rear wheels. Ignore this if you're on 2WD/ACKERMANN
#define MAX_STEERING_ANGLE 0.415  // max steering angle. This only applies to Ackermann st

RPM可以在车轮规格中找到,但CPR(COUNTS_PER_REV)是计算得出的值。
CPR = PPR x4。我们的车轮的PPR341。

* PPR可以在规格中查看,也可以在roslaunch linorobot minimal.launch机器人上运行代码并将车轮旋转360度。 PPR等于车轮旋转后将在屏幕上显示的数值:



* PPR = abs(RECENT_COUNT-INITIAL_COUNT)。

因此CPR =1364。您还需要以米为单位设置WHEEL_DIAMETER和LR_WHEELS_DISTANCE。此外,LR_WHEELS_DISTANCE是车轮中心轴之间的距离,而不是边缘之间的距离。如果机器人是两轮差速器(不是全向),则其他指示器可以忽略。

第三点可能会造成困难-IMU校准。为此,请按照说明将机器人固定在特定位置。当执行rosrun imu_calib do_calib脚本时,提示将出现在代码中



完成后,将生成带有设置的imu_calib.yaml。

尽管存在带有imu设置的默认文件,但执行校准还是更好的选择。
*此外,事实证明,imu校准会通过伸缩影响机器人的运动方向(左移而不是右移,反之亦然,来回移动正确)。不能通过重新布置代码中的引脚来解决这种情况。 Imu本身是固定的,并使用上下颠倒的支架进行了校准,因为固定在机器人基座的背面。他的(imu)进一步翻转而无需重新校准即可解决问题。

第四点-PID校准

在项目网站上,详细链接说明了如何执行调整的过程

但是,初学者很难弄清楚它是什么以及如何使用它。通常,需要进行快速调节以确保机器人均匀移动,而不会发生抽动/突然制动的情况。三个参数对此负责:p,i,d。它们的值包含在上传到teenzy的主要代码中:

#define K_P 2.0 // P constant angle
#define K_I 0.3 // I constant
#define K_D 0.1 // D constant

您可以通过在机器人上运行来进行实验:

roslaunch linorobot minimal.launch

在外部PC上的三个不同终端中:

rosrun lino_pid pid_configure
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
rqt

通过在rqt终端中移动滑块p,d,i,然后在teleop_twist_keyboard终端中控制机械手,您可以实现必要的结果,而不必每次都以teenzy的形式使用新的pid参数下载代码:



也就是说,一切都在进行中,并且当时在固件中进行teenzy可能具有完全不同的含义。*您不能专注于图表,因为 视觉上,因此可以理解机器人如何运行。

他们建议从设置值p = 1.0,d = 0.1,i = 0.1开始。在我们的情况下,值如下(通过实验获得)p = 2.0,i = 0.3,d = 0.1。

接下来,必须在代码中设置这些值并填写teenzy。

另外,不要忘记在代码中进行设置(DEBUG 0代替DEBUG 1):

#define DEBUG 0

里程表


为了确定机器人的方向并进行后续导航,使用了激光雷达数据,imu和车轮编码器数据。如果正确执行了imu校准,正确安装了激光雷达并且编码器值正确,则里程表应该没有问题。

要验证里程表是否正确,您需要通过望远镜在机器人上骑一点点,然后查看odom主题中的值,该主题写在项目页面链接上

并查看rviz的可视外壳:rviz中的



一个单元格为1 m,因此建议机器人在可视编辑器和实物中都通过该仪表。

此外,行进距离还显示在指示器w中:



也应趋向于1 m,

这同样适用于机器人的旋转角度:



*在rviz和live中,机器人必须以相同角度旋转。

激光雷达的里程表以类似的方式定义- 链接,从激光雷达到最近的活壁和rviz壁的距离应该匹配。

TF


在ROS中,特别注意转换-tf。概括而言,该概念描述了空间中物体彼此之间的相互关系。为了使物体不会悬空,并且程序了解它们是如何相对显示的,您需要注意tf设置。

在项目中,所有tf连接都已经相对于彼此进行了配置,您只需要调整指示器即可,例如,指示激光雷达的位置。对于机器人来说,必须了解到障碍物不是直接出现在他的前方,而是出现在激光雷达的前方,激光雷达与机器人的中心隔开一定距离。

让我们转到适当的目录:

roscd linorobot/launch
nano bringup.launch

底座本身与地板的距离为0.065 m:

<node pkg="tf_ros" type="static_transform_publisher" name="base_footprint_to_base_link" args="0 0 0.065 0 0 0  /base_footprint /base_link "/>

在laser.launch中,您需要设置激光雷达相对于机器人基座中心的位置:

roscd linorobot/launch/include
nano laser.launch

在我的情况下,激光雷达沿x轴移动:-0.08,y:0.04,并在基座上方(z轴)“上升”:0.08m:

<node pkg="tf2_ros" type="static_transform_publisher" name="base_link_to_laser"
args="-0.08 0.04 0.08 0 0 0  /base_link /laser "/>

在rviz中,可以从视觉上观察到此位置:



虽然距离激光雷达不远,但我们将调整其频率,使其发出更多点(默认情况下为4k),这将有助于构建地图:

cd linorobot/launch/include/lidar
nano rplidar.launch

添加参数:

<param name="scan_mode"  type="string" value="Boost"/>

并改变

<param name="angle_compensate"    type="bool"   value="false"/>

现在我们可以使用8k:



激光雷达在机器人上的物理位置也很重要:



建立2D房间地图


建议在项目网站上通过在两个终端中启动来构建房间地图:

roslaunch linorobot bringup.launch
roslaunch linorobot slam.launch

但是,实践表明,默认情况下该项目附带的slam在激光雷达模式为8k时拒绝工作:



在4k模式下,插卡效果不佳,但噪音很大。

因此,最好使用另一个猛击-hector-slam。此处

指示如何安装 安装后,创建地图的过程将是相同的,但是运行roslaunch my_hector_mapping my_launch.launch可以代替roslaunch linorobot slam.launch,运行roslaunch my_hector_mapping my_launch.launch 地图会更干净,但是最好在图形编辑器中进行修改,删除不必要的地图,尤其是在构建地图时激光雷达与镜子碰撞时。 : 别忘了保存房间地图:









rosrun map_server map_saver -f my-map

*在宜人的暮光下可以更好地获取地图,这将使预算激光雷达的收益最大化。

未完待续。

All Articles