小车yolo机械臂(六)ros gazebo 小车摄像头根据darknet_ros中yolo目标检测的信息进行自主运动
目录总览
小车yolo机械臂(一)ros下gazebo搭建小车(可键盘控制)安装摄像头仿真 加载yolo检测识别标记物体
小车yolo机械臂(二)机械臂仿真 ros下从xacro模型文件搭建Moveit!+Gazebo仿真系统
小车yolo机械臂(三)ROS消息订阅监听 rospy.Subscriber 订阅监听yolo python实现订阅/darknet_ros/bounding_boxes topic
小车yolo机械臂(四)python ros 和darknet_ros 使用launch文件启动脚本
小车yolo机械臂(五)让小车在命令下运动起来 rostopic pub /cmd_vel geometry_msgs/Twist
小车yolo机械臂(六)ros gazebo 小车摄像头根据darknet_ros中yolo目标检测的信息进行自主运动
小车yolo机械臂(七)小车与机械臂融合,并控制机械臂运动 gazebo control
小车yolo机械臂(八)ros小车和机械臂gazebo仿真,机械臂根据darknet_ros中yolo检测结果来自动运动 python实现
前言
前面几篇博客已经实现了小车通过命令行运动,以及yolo检查结果信息的输出,那么现在我们要将这两者融合在一起。根据darkenet_ros中yolo的结果(比如前方检测出有人,小车启动,向前)自动进行运动。
rospy.Publisher()
我们要将控制小车运动的代码,写到listener_yolo.py文件中,在这个python文件中,已经实现了yolo检测目标的输出,那么现在我们要实现的就是将小车运动的命令植入到这个python文件中。
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
我们用到rospy.Publisher,这是话题的一个发布,这里用到的是Twist消息类型,因为/cmd_vel这个话题所对应的消息类型为:geometry_msgs/Twist (上一个博客有讲解)
所以我们在python文件的顶部,要导入:
from geometry_msgs.msg import Twist
queue_size 这里比较复杂,我就直接粘贴复制其它博主的讲解了:
rospy中的publish()默认是阻塞式同步发送模式。这将导致连接断开后publish卡死(比如无线连接的publisher和subscriber)。
不过,可以将publish和subscribe的queue_size写入一个大于0的值使publish成为异步模式。
- queue_size: None(不建议)
这将设置为阻塞式同步收发模式! - queue_size: 0(不建议)
这将设置为无限缓冲区模式,很危险! - queue_size: 1,2,3
对于只关心最新数据的sensor消息,可以设为1;
对于系统负载不高,能及时处理的消息,可以设为1,2,3. - queue_size: 10 or more
- 一般情况下,设为10 。queue_size太大了会导致数据延迟不同步
更多请参考:
ROS笔记:Python
ROS订阅最新的消息及queue_size和buff_size的理解
ROS进二阶学习笔记(10) – rospy.Publisher() 之 queue_size
08.ROS入门学习 - 用python写 Publisher 和 Subscriber
rospy让小车自主动起来
在mrobot_gazebo/scripts下创建listener_yolo.py
直接上代码:
#!/usr/bin/env python
import rospy
from darknet_ros_msgs.msg import BoundingBoxes
from geometry_msgs.msg import Twist
def callback(data):
print data.bounding_boxes[0].Class
if data.bounding_boxes[0].Class == 'person':
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
desired_velocity = Twist()
desired_velocity.linear.x = 0.1
desired_velocity.angular.z = 0
pub.publish(desired_velocity)
print "go on"
def listener():
rospy.init_node('topic_subscriber')
sub = rospy.Subscriber('/darknet_ros/bounding_boxes', BoundingBoxes, callback)
rospy.spin()
if __name__ == '__main__':
listener()
当然,这个python文件也需要对它进行权限增加,不然无法执行。
在listener_yolo所在目录执行
chmod +x listener_yolo.py
:
相应的,在my_gazebo3.launch里的文件也要添加这个python文件
代码如下:
<launch>
<!-- 设置launch文件的参数 -->
<arg name="world_name" value="$(find mrobot_gazebo)/worlds/playground.world"/>
<arg name="paused" default="false"/>
<arg name="use_sim_time" default="true"/>
<arg name="gui" default="true"/>
<arg name="headless" default="false"/>
<arg name="debug" default="false"/>
<!-- 运行gazebo仿真环境 -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(arg world_name)" />
<arg name="debug" value="$(arg debug)" />
<arg name="gui" value="$(arg gui)" />
<arg name="paused" value="$(arg paused)"/>
<arg name="use_sim_time" value="$(arg use_sim_time)"/>
<arg name="headless" value="$(arg headless)"/>
</include>
<!-- 加载机器人模型描述参数 -->
<param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mrobot_gazebo)/urdf/my_gazebo_robot_All.urdf.xacro'" /> \
<!-- 运行joint_state_publisher节点,发布机器人的关节状态 -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node>
<!-- 运行robot_state_publisher节点,发布tf -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen" >
<param name="publish_frequency" type="double" value="50.0" />
</node>
<!-- 在gazebo中加载机器人模型-->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model mrobot -param robot_description"/>
<!-- 启动darknet_ros的yolo检测-->
<include file="$(find darknet_ros)/launch/darknet_ros.launch">
</include>
<!-- 启动监听订阅yolo检测话题的python --><!---->
<node pkg="mrobot_gazebo" name="listener_yolo" type="listener_yolo.py" output="screen">
</node>
</launch>
我们启动模型:
roslaunch mrobot_gazebo my_gazebo3.launch
现在小车还是静止的,我们在小车模型前面放置一个人。
小车检测到前方有人,就开始移动
在终端也小车也打印出了移动的结果。