ROS 远程控制之码率问题

本文记录了一个基于WiFi通讯的ROS控制实验过程,详细分析了实验中遇到的高码率问题,并提出了针对地图数据压缩的解决方案。

前不久, 做了一个WiFi通讯的ROS控制实验。(注: 是在同一个wifi网段下,没有跨internet). 众所周知,ROS middleware是一个分布式框架(严格来说是一个星形分布,需要一个master)。经过简单的设置便可以实现各个节点的wifi 通讯。

于是做了以下两个实验:

1》 hector slam 建立地图

2》 基于已有地图的navigation

这两个过程中, 机器人Robot和笔记本Notebook分布负责算法运行, rviz 显示 + 键盘控制。 一切都比较顺利, 但其中有一个问题引发了我的注意。 整个实验过程中码率都很高,如图所示:第一张图是机器人不动的时候, 码率峰值达到了1MB/s, 当机器人运动起来时, 码率高达2MB/s. 码率呈周期性变化。




主要的码流是由于Notebook 主要是订阅了一些消息所产生的, 于是去查询最占流量的信息, 地图。

地图的格式是

建立地图和自动导航阶段的主要数据量是 地图数据,其次是激光数据。不订阅或者降低这两个topic订阅频率,那么数据量会大幅减小。

从代码和配置信息可以发现地图的发布周期是2秒

  private_nh_.param("map_pub_period", p_map_pub_period_, 2.0);

这也映证了网络流量图的波动情况。


此外,地图数据在传送过程中没有做任何数据压缩,所以还存在很大的数据压缩空间。

1> 根据无损压缩图像的经验,在合适的计算量下,估计可以压缩5~10倍率。考虑到地图数据中有大量的相似取值,采用算术熵编码可以大幅降低码率。

2> 甚至可以考虑简化数据的方式, 将取值进一步重新量化,比如将概率取值分3个段。这样可以直接将每位8bit降到2bit, 数据量直接下降为原来的1/4

如果两种方式都采用,地图数据量很有把握地肯定可以下降10倍以上。


ros是大家广为学习的middleware, 其中实时性是一大诟病,在此,我也有个小小的建议,ROS应该提供一些数据压缩和解压方式提供给有此类需求的人。我还不清楚现有的ROS究竟有没有,从我本次测试来看,应该是没用到。 如果没有的话, 年后我会做一个。希望广大网友多多支持。

我自己也发现了一个问题: 如果网络流量主要是地图形成, 而且数据如果没有压缩的话, 应该是很稳定的波动(因为地图尺寸没有变化, 如果只是传递地图有效区域,那么流量应该随着地图越来越大而增长)。不应该在小车出现移动的情况下发生变化。

 现在的现象是有变化的, 说明流量的可能受到其他因素的影响。有可能是发送延时。如果是发送延时,那么流量波动在一定窗口期内还是比较均匀的。目前好像确实比较符合。

还需要多做实验测试wifi信号好和不好的情况下的波动情况。也可以抓数据看看。

继续实验:

首先将发布周期改为5秒, 将小车从wifi 近处开到远处, 会得到下图的情况: 单位时间内(10秒为单位),总流量没有变,波形发生改变,是因为码率峰值上不去,发送延时所导致。


然后将小车遥控回来,情况是这样的:




关闭绝大部分订阅, 只保留TF的订阅(方便看到车在动),会看到码率一下子几乎到0

在上一步的基础上,增加激光雷达的数据订阅, 可以看到数据量 每秒大概是40kB,  我的激光雷达是每秒4000点, 主要数据 每个点有两个 float, 所以总数据量应该是 4K × 8Byte = 32KB.  再加上其他的头部信息和ROS开销,接近40KB 是非常准确的。 由此也可以推断出,数据在wifi传输过程中应该是没有任何压缩的。


最后一张是建立地图完成之后的码率情况。 整个建图面积大概有100平米左右, 与刚开始前的 10平米小房间, 没有什么码率差别。 由此可以推断ROS是整图传输的,没有使用任何稀疏表示或者区域表示的方式。也没有任何数据压缩措施。

很有必要针对ROS写一个数据压缩节点, 将数据压缩之后上传网络, 另一端从网络下载之后,在解压节点进行解压,这样可以大幅优化ROS通过网络进行监控和遥控的实时性。

本问题暂时到此告一段路。 实验结论已经明确,与代码完全吻合。



### 实现基于ROS的小车远程控制 要通过ROS实现4G网络下的小车远程控制,可以采用以下方法: #### 1. **硬件准备** 为了实现这一目标,需要准备好必要的硬件设备。通常情况下,这包括一台运行ROS系统的嵌入式计算机(如树莓派或NVIDIA Jetson Nano),以及支持4G通信的模块(如SIM800L、EC25等)。此外,还需要确保小车具备基本的驱动电机和传感器接口。 #### 2. **软件架构设计** 在ROS环境中,可以通过发布/订阅机制来实现远程命令传输和状态反馈。具体来说: - 创建一个用于接收来自4G模块数据的主题节点。 - 将接收到的数据解析并转换为小车运动指令。 - 发布这些指令到相应的执行器主题上。 #### 3. **配置4G模块** 对于大多数常见的4G模块而言,它们往往提供串口通信方式与主机相连。因此,在Linux系统下需先安装对应的驱动程序,并设置好波特率等相关参数以便正常工作[^1]。 ```bash sudo apt-get update && sudo apt-get install -y python-pip python-serial pip install pyserial ``` 接着编写简单的Python脚本来测试连接情况: ```python import serial ser = serial.Serial('/dev/ttyUSB0', baudrate=9600, timeout=1) def send_command(cmd): ser.write((cmd+'\r\n').encode()) if __name__ == "__main__": while True: cmd=input("Enter AT command:") send_command(cmd) response=ser.readline().decode('utf-8') print(response.strip()) ``` #### 4. **构建ROS节点** 接下来就是创建实际使用的两个主要ROS节点——一个是负责处理从互联网传来的遥控信号;另一个则是用来监听本地话题并将结果发送给物理层控制器。 ##### 遥控端节点 (`remote_control_node.py`) 此部分负责建立WebSocket服务器或者HTTP API服务端点接受外部请求,然后将其转化为标准化的消息格式再广播出去供其他组件消费。 ```python #!/usr/bin/env python import rospy from std_msgs.msg import String import websockets import asyncio async def handler(websocket, path): async for message in websocket: pub.publish(String(data=message)) rospy.init_node('remote_controller', anonymous=True) pub = rospy.Publisher('command_topic', String, queue_size=10) start_server = websockets.serve(handler, 'localhost', 8765) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever() ``` ##### 执行机构控制节点(`actuator_control_node.cpp`) 这部分代码会持续读取前面定义好的topic中的最新值,并据此调整马达的速度方向等等属性。 ```cpp #include "ros/ros.h" #include "std_msgs/String.h" void callback(const std_msgs::String& msg){ // 解析msg.data得到具体的动作指令... } int main(int argc, char **argv){ ros::init(argc, argv, "actuator_control"); ros::NodeHandle nh; ros::Subscriber sub = nh.subscribe("command_topic", 10, &callback); ros::spin(); } ``` 以上仅作为概念性的框架展示,请根据实际情况修改完善各个细节之处。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值