< >
Home » ROS与AR.Drone教程 » ROS与AR.Drone-ardrone_tutorials-标签检测和反馈处理

ROS与AR.Drone-ardrone_tutorials-标签检测和反馈处理

标签检测和反馈处理

说明

  • 本篇介绍如何检测标签并获取反馈内容,并处理。

准备

  • 找到Orange-[Green|Yellow|Blue]-Orange 的标签,可以是贴纸。
  • 编辑launch
$ vim keyboard_controller_with_tags.launch

$ vim joystick_controller.launch
  • 更改内容
找到<param name="enemy_colors" value="3" />
  • enemy_colors的值和标签的对应
1->Orange-Green-Orange
2->Orange-Yellow-Orange
3->Orange-Blue-Orange

标签检测和反馈数据

  1. 启动,不起飞
$ roslaunch ardrone_tutorials keyboard_controller_with_tags.launch

$ roslaunch ardrone_tutorials joystick_controller.launch
  1. 打开新终端,显示所有主题
$ rostopic list
  1. 同终端再显示导航数据
$ rostopic echo /ardrone/navdata
  • 显示反馈的数据
  • 因为没起飞,很多数据为0。
  1. 在前相机移动Orange-Color-Orange标签,应该被检测,终端显示相应数据
  • 注意tags_xc 和tags_yc值,是标签在图片中的x/y位置
  • 视频显示窗口将在这些坐标显示一个点,并在点上方的距离测量
  1. 放置标签到飞行器可见的地方,让飞行器起飞。

  2. 在终端观察数据变化,当进行不同飞行动作。

绘制AR.Drone的状态

  1. 启动rxplot
$ rxplot /ardrone/navdata/rotX,/ardrone/navdata/rotY
  • 显示飞行器的roll (rotX) 和 pitch (rotY) 曲线图
  • 其他图如 yaw (rotZ), x和y velocity (vx and vy), altitude (altd)等
  1. 通过绘图方式研究飞行器如何飞行
$ rxplot /cmd_vel/linear/y,/cmd_vel/linear/x
  • 这个绘制 roll (linear/y) and pitch (linear/x) 命令.
  • 有一个最大可控角度值$\pm1$,可通过启动文件的参数euler_angle_max设置。
  • 注意移动的方向:move along the x-axis = /cmd_vel/linear/x = commanded pitch , tilt around y-axis = /ardrone/navdata/rotY = feedback pitch

记录数据

  1. 记录数据,通过rosbag来是实现
$ rosbag record -O ARDroneFlight.bag /ardrone/navdata /cmd_vel
  • 这命令将会记录/ardrone/navdata和/cmd_vel到“ARDroneFlight.bag”,可命其他名字
  • 保持飞行一段时间在按 Ctrl-C 中止
  • 可以记录全部数据,通过-a参数,但是这样会保存视频流,数据包会变得非常大
  1. 降落飞行器,关闭所有终端。重开终端
$ roscore
  1. 新终端
$ rxplot /cmd_vel/linear/y,/cmd_vel/linear/x
  1. 重放
$ rosbag play ARDroneFlight.bag

自定义数据处理

这一节介绍如何写一个节点来处理反馈数据,还可以通过反馈来控制飞行器。ROS通过主题的订阅和发布来通讯。

  1. 查看主题信息
rosmsg show ardrone_autonomy/Navdata
  1. 内容
$ rosmsg show ardrone_autonomy/Navdata
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
float32 batteryPercent
uint32 state
int32 magX
int32 magY
int32 magZ
int32 pressure
int32 temp
float32 wind_speed
float32 wind_angle
float32 wind_comp_angle
float32 rotX
float32 rotY
float32 rotZ
int32 altd
float32 vx
float32 vy
float32 vz
float32 ax
float32 ay
float32 az
uint32 tags_count
uint32[] tags_type
uint32[] tags_xc
uint32[] tags_yc
uint32[] tags_width
uint32[] tags_height
float32[] tags_orientation
float32[] tags_distance
float32 tm
  1. 最小可行的订阅
  • 编写minimum_viable_subscriber.py
$ roscd ardrone_tutorials
$ vim src/minimum_viable_subscriber.py
  • 内容
import roslib
import rospy

roslib.load_manifest('ardrone_tutorials')

from ardrone_autonomy.msg import Navdata

def ReceiveData(data):
  print '[{0:.3f}] Pitch: {1:.3f}'.format(data.header.stamp.to_sec(), data.rotY)

rospy.init_node('minimum_viable_subscriber')
sub_Navdata = rospy.Subscriber('/ardrone/navdata', Navdata, ReceiveData)

while not rospy.is_shutdown():
  pass
  1. 测试代码
  • 新终端打开
$ roscore
  • 新终端打开
$ roscd ardrone_tutorials
$ python src/minimum_viable_subscriber.py
  1. 回放
$ rosbag play ARDroneFlight.bag
  1. 反馈,在运行代码的终端可看到,提取了Pitch部分的数据
[1353596639.491] Pitch: 4.375
[1353596639.511] Pitch: 4.128
[1353596639.531] Pitch: 3.750
[1353596639.552] Pitch: 3.304
[1353596639.571] Pitch: 3.063

分析上述订阅代码

  1. 代码
import roslib
import rospy

导入ROS包

  1. 代码
roslib.load_manifest('ardrone_tutorials')

加载项目的manifest文件,其中包含项目的依赖。

  1. 代码
from ardrone_autonomy.msg import Navdata

导入需要的节点

  1. 代码
def ReceiveData(data):
  print '[{0:.3f}] Pitch: {1:.3f}'.format(data.header.stamp.to_sec(), data.rotY)

定义回调函数函数处理Navdata信息,并格式化输出Pitch数值

  1. 代码
rospy.init_node('minimum_viable_subscriber')

初始化节点

  1. 代码
sub_Navdata = rospy.Subscriber('/ardrone/navdata', Navdata, ReceiveData)

订阅主题信息,并交给回调函数处理

  1. 代码
while not rospy.is_shutdown():
  pass

如果不中止就一直处理信息

发布数据

  1. 最小可行的发布
  • 创建 minimum_viable_publisher.py,内容发布到/ardrone/average_pitch主题
  • 文件内容
import roslib
import rospy

roslib.load_manifest('ardrone_tutorials')

from ardrone_autonomy.msg import Navdata
from std_msgs.msg import String

messages = []

def ReceiveData(data):
  messages.append(data)

rospy.init_node('minimum_viable_publisher')
sub_Navdata = rospy.Subscriber('/ardrone/navdata', Navdata, ReceiveData)
pub_Average = rospy.Publisher('/ardrone/average_pitch', String)

r = rospy.Rate(1)
while not rospy.is_shutdown():
  if len(messages)>0:
    avg = sum([m.rotY for m in messages])/len(messages)
    messages = []

    avgmsg = String()
    avgmsg.data = 'Average Pitch: {0:.3f}'.format(avg)
    pub_Average.publish(avgmsg)
  r.sleep()
  1. 运行
#新终端
$ roscore

#新终端
$ roscd ardrone_tutorials
$ python src/minimum_viable_publisher.py

#新终端
$ rostopic echo /ardrone/average_pitch


#新终端
$ rosbag play ARDroneFlight.bag

#回到rostopic echo终端
data: Average Pitch: 0.649
---
data: Average Pitch: 1.078
---
data: Average Pitch: 3.781
---
data: Average Pitch: 3.285
---
  1. 分析代码
  • 代码
from ardrone_autonomy.msg import Navdata
from std_msgs.msg import String

导入需要的库

  • 代码
messages = []
def ReceiveData(data):
  messages.append(data)

定义回调函数,并数据到队列里

  • 代码
pub_Average = rospy.Publisher('/ardrone/average_pitch', String)

发布主题为字符串内容,发布到主题/ardrone/average_pitch

  • 代码
r = rospy.Rate(1)

定义rate函数,控制处理频率,目前控制1秒。

  • 代码
while not rospy.is_shutdown():
  if len(messages)>0:
    avg = sum([m.rotY for m in messages])/len(messages)
    messages = []

    avgmsg = String()
    avgmsg.data = 'Average Pitch: {0:.3f}'.format(avg)
    pub_Average.publish(avgmsg)

如果收到信息,我们将会通过记录的数据计算平均值,转成字符值发布到主题上。

  • 代码
r.sleep()

进行睡眠状态,之后再进入下一个循环在计算。

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ros ar.drone, ros 标签检测, ros ar.drone 反馈处理