kobuki driver的逻辑分析

玩kobuki设备的人都知道可以在上面运行不同的原生程序,像turtlebot_teleop keyboard_teleop.launch,turtlebot_navigation gmapping_demo.launch等等,这些原生程序就像是跑在机器上的app,由于kobuki driver对上对下都提供了详细的通信方式。因此想充分了解kobuki,重点要分析kobuki driver。

对上ros apps 的通信方式为ros topics,详细信息见前面的文章:turtlebot的mobile_base节点

对下kobuki firmware 的通信方式为 serial 读写,详细信息见前面的文章:kobuki驱动通信规范

本文主要介绍kobuki driver的主要逻辑和从firmware读出的主要信息如何转成apps需要的topics

在ros中程序都以节点方式存在,运行 roslaunch turtlebot_bringup minimal.launch,显示

process[robot_state_publisher-2]: started with pid [27357]
process[diagnostic_aggregator-3]: started with pid [27358]
process[mobile_base_nodelet_manager-4]: started with pid [27359]
process[mobile_base-5]: started with pid [27368]
process[bumper2pointcloud-6]: started with pid [27380]
process[cmd_vel_mux-7]: started with pid [27393]
process[turtlebot_laptop_battery-8]: started with pid [27409]
process[capability_server-9]: started with pid [27420]
process[app_manager-10]: started with pid [27428]
process[master-11]: started with pid [27429]
process[interactions-12]: started with pid [27443]
process[zeroconf/zeroconf-13]: started with pid [27448]

看上去是好多个节点进程都有各自的pid,但其中很多节点都采用了nodelete方式,运行在同一个进程中,详细信息见前面的文章:ros中的nodelet

其中主要的代码文件为kobuki.cpp,kobuki_ros.cpp,kobukiNodelet.cpp,编译生成的文件为libkobuki_nodelet.so,以动态库的形式存在。拉起kobuki节点相当动态加载ibkobuki_nodelet.so。在xxx/turtlebot_bringup/launch/includes/kobuki/mobile_base.launch.xml 中可以看到如下:

<node pkg="nodelet" type="nodelet" name="mobile_base" args="load kobuki_node/KobukiNodelet $(arg manager)">

从而得出结论,是mobile_base_nodelet_manager这个进程加载了libkobuki_nodelet.so,而kobuki node的名字就是mobile_base。

备注:节点和进程不是一一对应的,一个进程可以只包含一个节点,一个进程还可以包含多个节点。


入口:当加载动态库时,”load kobuki_node/KobukiNodelet $(arg manager)“

1.首先执行代码为kobukiNodelet.cpp的onInit(),在该函数中先调用kobuki_ros.cpp中的init(),代码如下:

if (kobuki_->init(this->getPrivateNodeHandle(), this->getNodeHandle()))

然后启动一个线程时刻更新状态

update_thread_.start(&KobukiNodelet::update, *this);


  2.查看kobuki_ros.cpp中的init()

2.1先定义了发布和订阅的topics

  advertiseTopics(nh);
  subscribeTopics(nh);

2.2定义了一系列slot句柄,方便后续直接使用slot句柄发布接收topics。

2.3设置一系列Driver Parameters。

2.4设置轮胎Joint States的参数

2.5初始化了odometry参数和信息,因为tf只涉及到位置坐标的变换,而kobuki的线速度和角速度则有odometry来计算并发布。

2.6初始化驱动,即调用kobuki.cpp的init()函数。


3.查看kobuki.cpp的init()函数

3.1初始化一些Signals句柄,用来发布订阅各自的主题

3.2打开通信串口

serial.open(parameters.device_port, ecl::BaudRate_115200, ecl::DataBits_8, ecl::StopBits_1, ecl::NoParity); 

3.3通过串口获取一些kobuki基础信息

3.4启动线程Kobuki::spin,代码如下

thread.start(&Kobuki::spin, *this);


4.查看Kobuki::spin代码,主要逻辑都在这个线程里实现

4.1 建立一个循环,当发送关闭请求后才会从循环中跳出

while (!shutdown_requested)

4.2 在这个循环中,不停地读串口中的数据,鉴于kobuki firmware 以50Hz的频率不停地通过串口上传基础信息,包括()。在循环中每次读完数据就不进行sleep操作。

4.3 读完串口信息后处理这些基础信息,转成topics格式发布出去

4.4 下发基础运动命令,也已50Hz的频率下发。这里有个注意点:如果apps没有操作kobuki运动,则下发的命令(线速度,角速度)均为0。

sendBaseControlCommand();

5.额外的命令下发

diver 通过订阅topics知道ros apps下发的命令

除了订阅的基础运动topics(commands/controller_info),剩余dirver订阅的topics,均不再spin线程中处理,由相关注册函数直接调用serial.write命令下发的firmware上。见subscriber_callbacks.cpp,由订阅的topics注册函数

这里没看到有锁,故应该会有命令下发的冲突吧。这里还需要详细查看代码。


6.odom

见~~~





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值