在ros中进行无人机和无人车之间的通信(代码)
在ros中进行无人机和无人车之间的通信
- 代码存放位置以及运行所必要的编译步骤
- 无人机端
- 1.创建ROS工作空间
- 2.组织代码
- 3.编译
- 4.启动文件
- 无人车端
- 1.创建工作空间和包
- 2.组织代码
- 3.编译
- 4.启动文件
- 目录结构总结
- 配置网络和启动
- 1.网络配置
- 2.启动ROS核心
- 3.启动节点
- 调试和验证
要实现无人车和无人机之间通过ROS(Robot Operating System)进行通信,双方既需要接收数据也要发布数据。
无人机平台:
- 接收无人车传输的
lat_lon_car
(经度、纬度、高度),通过location()
函数处理生成目标位置lat_lon_target
。- 将
lat_lon_target
发布回给无人车。无人车平台:
- 发布它当前的经度、纬度和高度数据(
lat_lon_car
)。- 接收无人机平台传回的
lat_lon_target
。ROS的通信机制基于发布/订阅模式(Publish/Subscribe),其中一个节点可以通过话题(topics)发布消息,另一个节点通过订阅同一个话题来接收消息。
关键步骤:
消息类型: 为了传输经度、纬度和高度数据,可以使用标准的
sensor_msgs/NavSatFix
消息类型(常用于GPS数据传输)。通信话题:
- 无人车发布
lat_lon_car
数据到一个ROS话题,例如car_position
。- 无人机订阅
car_position
话题,并处理数据,然后将生成的lat_lon_target
发布到drone_target
话题。- 无人车同时订阅
drone_target
,接收无人机发布的目标位置。代码解释:
无人车节点 (
car.py
):
- 通过
car_position
话题发布当前的位置信息(NavSatFix
类型)。- 同时通过
drone_target
话题订阅无人机发布的目标位置。无人机节点 (
drone.py
):
- 通过
car_position
话题订阅无人车的当前位置。- 使用
location()
函数处理接收到的lat_lon_car
数据,生成目标位置信息。- 通过
drone_target
话题将目标位置信息发布给无人车。通信原理:
- 发布者(Publisher):每个节点通过
rospy.Publisher()
来发布消息。- 订阅者(Subscriber):每个节点通过
rospy.Subscriber()
来接收其他节点发布的消息。- 无人车节点持续发布自己的位置信息,无人机节点接收到这些信息后,生成目标位置并发布回来。
代码存放位置以及运行所必要的编译步骤
无人机端
1.创建ROS工作空间
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_create_pkg drone_package std_msgs rospy roscpp #创建了一个包
#这一步后会在drone_package中生成下面几个文件
~/catkin_ws/
├── src/
│ ├── drone_package/
│ │ ├── CMakeLists.txt
│ │ ├── package.xml
│ │ ├── src
创建一个名为 catkin_ws 的ROS工作空间,其中 src 文件夹用于存放ROS包。
2.组织代码
在drone_package/src/目录下,编写无人机的代码(例如,定位算法):
drone_node.py文件
#!/usr/bin/env python
import rospy
from sensor_msgs.msg import NavSatFix# 定义全局变量,用来存储无人车的位置信息
lat_lon_car = Nonedef location(lat_lon_car):# 这个函数根据无人车的位置信息,生成无人机的目标位置# 假设简单的目标生成逻辑,比如偏移当前位置一定的值lat_lon_target = NavSatFix()lat_lon_target.latitude = lat_lon_car.latitude + 0.001 # 例如,增加一些纬度lat_lon_target.longitude = lat_lon_car.longitude + 0.001 # 例如,增加一些经度lat_lon_target.altitude = lat_lon_car.altitude # 保持高度不变return lat_lon_targetdef car_position_callback(data):global lat_lon_carlat_lon_car = datarospy.loginfo("Received car position: latitude=%f, longitude=%f, altitude=%f" %(data.latitude, data.longitude, data.altitude))def drone_node():rospy.init_node('drone_node', anonymous=True)# 订阅无人车的位置信息rospy.Subscriber('car_position', NavSatFix, car_position_callback)#NavSatFix是专门的gps数据,用car_position_callback()这个回调函数进行解析# 创建发布器,发布目标位置给无人车pub = rospy.Publisher('drone_target', NavSatFix, queue_size=10)rate = rospy.Rate(1) # 1Hz,定义发布频率为1次每秒while not rospy.is_shutdown():if lat_lon_car is not None:lat_lon_target = location(lat_lon_car)rospy.loginfo("Publishing target position: latitude=%f, longitude=%f, altitude=%f" %(lat_lon_target.latitude, lat_lon_target.longitude, lat_lon_target.altitude))pub.publish(lat_lon_target)rate.sleep()if __name__ == '__main__':try:drone_node()except rospy.ROSInterruptException:pass
3.编译
cd ~/catkin_ws
catkin_make
4.启动文件
在drone_package/launch/目录下创建启动文件drone_launch.launch:
<!-- drone_launch.launch -->
<launch><node pkg="drone_package" type="drone_node.py" name="drone_node" output="screen"/>
</launch>
无人车端
1.创建工作空间和包
在无人车计算机上,创建ROS工作空间和包:
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_create_pkg vehicle_package std_msgs rospy roscpp
2.组织代码
在vehicle_package/src/目录下,编写无人车的代码(例如,检测算法):
#!/usr/bin/env python
import rospy
from sensor_msgs.msg import NavSatFixdef publish_car_position():rospy.init_node('car_node', anonymous=True)# 创建发布器,发布无人车的位置信息pub = rospy.Publisher('car_position', NavSatFix, queue_size=10)# 创建订阅器,接收无人机发布的目标位置rospy.Subscriber('drone_target', NavSatFix, drone_target_callback)rate = rospy.Rate(1) # 1Hz,定义发布频率为1次每秒while not rospy.is_shutdown():# 生成无人车的当前位置数据lat_lon_car = NavSatFix()lat_lon_car.latitude = 37.7749 # 举例:设定某个纬度lat_lon_car.longitude = -122.4194 # 举例:设定某个经度lat_lon_car.altitude = 30.0 # 举例:设定高度为30米rospy.loginfo("Publishing car position: latitude=%f, longitude=%f, altitude=%f" %(lat_lon_car.latitude, lat_lon_car.longitude, lat_lon_car.altitude))pub.publish(lat_lon_car)rate.sleep()def drone_target_callback(data):rospy.loginfo("Received target position from drone: latitude=%f, longitude=%f, altitude=%f" %(data.latitude, data.longitude, data.altitude))if __name__ == '__main__':try:publish_car_position()except rospy.ROSInterruptException:pass
3.编译
cd ~/catkin_ws
catkin_make
这一步以后文件架构变为如下:
~/catkin_ws/
├── src/
│ ├── drone_package/
│ │ ├── CMakeLists.txt
│ │ ├── package.xml
│ │ ├── launch
│ │ ├── src/
│ │ │ └── drone_node.py
└── build
└── devel
4.启动文件
在vehicle_package/launch/目录下创建启动文件vehicle_launch.launch:
<!-- vehicle_launch.launch -->
<launch><node pkg="vehicle_package" type="vehicle_node.py" name="vehicle_node" output="screen"/>
</launch>
目录结构总结
最终你的工作空间应该具有以下结构:
~/catkin_ws/
├── src/
│ ├── drone_package/
│ │ ├── CMakeLists.txt
│ │ ├── package.xml
│ │ ├── launch/
│ │ │ └── drone_launch.launch
│ │ ├── src/
│ │ │ └── drone_node.py
│ │ └── scripts/
│ └── ...
└── devel/└── ...
~/catkin_ws/
├── src/
│ ├── vehicle_package/
│ │ ├── CMakeLists.txt
│ │ ├── package.xml
│ │ ├── launch/
│ │ │ └── vehicle_launch.launch
│ │ ├── src/
│ │ │ └── vehicle_node.py
│ │ └── scripts/
│ └── ...
└── devel/└── ...
配置网络和启动
1.网络配置
确保两台计算机在同一网络下,并可以互相访问。需要设置ROS主机和ROS主机IP地址:
无人机上:
export ROS_MASTER_URI=http://<无人机计算机的IP>:11311
export ROS_IP=<无人机计算机的IP>
无人车上:
export ROS_MASTER_URI=http://<无人机计算机的IP>:11311
export ROS_IP=<无人车计算机的IP>
2.启动ROS核心
在无人机计算机上,启动ROS核心:
roscore
3.启动节点
在无人机计算机上,启动无人机节点:
roslaunch drone_package drone_launch.launch
在无人车计算机上,启动无人车节点:
roslaunch vehicle_package vehicle_launch.launch
调试和验证
确保在ROS核心终端和各自的节点终端中没有错误信息。你可以使用rostopic命令检查消息是否正确发布和订阅:
rostopic echo /drone_target
rostopic echo /vehicle_result