Tag Archives: ROS

AR.Drone四轴飞行器ROS开发方法介绍

之前有人咨询如何在AR.Drone平台上进行开发,这里就简单介绍一下AR.Drone在Linux和ROS (Robot Operating System) 下的开发方法。原来计划是一篇更加完整的开发介绍,但是因为中间搁置了一段时间,很多细节到现在已经不能完全记清楚了,所以只简单介绍一下工具及方法。开发过程是在我的研究生毕业设计: Vision-Based Localization and Tracking of a UGV with a Quadcopter中整理的,该项目的介绍和演示视频可以在这里找到

AR.Drone是法国Parrot公司生产的高性能四轴飞行器平台,它因其极高的性价比和丰富的板载传感器而被广泛应用于机器人研究中。AR.Drone平台于2010年在CES大会上首次发布,它最初的定义是应用于虚拟增强游戏的高科技四轴飞行器平台。AR.Drone使用了极轻的聚丙烯和碳纤维材料,不含外壳的总重量仅为380g。AR.Drone可用于室内或室外飞行,每一种模式可以配备不同的外壳。其第二代AR.Drone 2.0于2012年发布,相对于一代增强了摄像头分辨率,并提高了处理器性能。新版本的AR.Drone 2.0 (Power Edition) 还支持使用GPS定位模块,同时续航时间由最初的18分钟提高到了40分钟。AR.Drone丰富的传感器及极佳的稳定性,让其十分适合于机器人研究。相比于固定翼平台,四轴平台无需太大的实验场地,从而更适合于室内飞行实验。

ardrone
图1. Parrot公司的AR.Drone 2.0四轴飞行器

整个系统是服务器-客户端架构,其中AR.Drone作为服务器,对用户提供WiFi接口,需要用户主动去连接。其官方提供的SDK (AR.Drone SDK) 向用户提供了飞行姿态数据、视频流以及用户控制命令接口,基于该SDK可以使用C或C++进一步扩展功能,如增加路径规划导航及图像识别等。该SDK的具体使用方法我并没有仔细研究过,命令和数据好像在是建立socket连接后通过AT指令传输的,详情可以参见开发手册

在我的项目中,我并没有使用AR.Drone SDK,而是使用了AR.Drone SDK的二次封装库:ardrone-autonomy. ardrone-autonomy是在ROS下实现的,所以需要ROS和Linux Ubuntu开发环境。ROS Hydro版本的安装方法在我另一篇博文中。

Ubuntu和ROS的安装工作完成后,在terminal中输入以下指令安装ardrone-autonomy:

apt-get install ros-hydro-ardrone-autonomy

如果不是使用的ROS Hydro而是其他版本,则将-hydro-换为对应版本:-Indigo-或-Groovy-。安装完成后,通过rosrun运行驱动:

rosrun ardrone_autonomy ardrone_driver

运行之前确定WiFi需要确定正常连接。如果连接失败,命令提示行中会有对应的提示输出。该驱动在运行时还可以修改配置参数:

# Default Setting - 50Hz non-realtime update, the drone transmission rate is 200Hz
$ rosrun ardrone_autonomy ardrone_driver _realtime_navdata:=False  _navdata_demo:=0

# 200Hz real-time update
$ rosrun ardrone_autonomy ardrone_driver _realtime_navdata:=True _navdata_demo:=0

# 15Hz real-rime update
$ rosrun ardrone_autonomy ardrone_driver _realtime_navdata:=True _navdata_demo:=1

其中,_realtime_navdata 参数决定数据是否缓冲发送,而_navdata_demo 参数决定数据的发送频率是15Hz还是200Hz。该驱动运行成功后,将作为一个Node向外Publish或者Subscribe topics。topics有三类,前两个为数据输出,后一个为命令输入:

1) Legacy navigation data,位于ardrone/navdata,包括当前状态、转角、速度、加速度等:

  • header: ROS message header,消息头

  • batteryPercent: The remaining charge of the drone’s battery (%),电池电量

  • state: The Drone’s current state,当前飞行器状态:
    • 0: Unknown,未知
    • 1: Inited,初始化完成
    • 2: Landed,着陆
    • 3,7: Flying,飞行
    • 4: Hovering,悬停
    • 5: Test (?),测试
    • 6: Taking off,正在起飞
    • 8: Landing,正在着陆
    • 9: Looping (?)
  • rotX: Left/right tilt in degrees (rotation about the X axis),左右倾角Roll

  • rotY: Forward/backward tilt in degrees (rotation about the Y axis),前后倾角Pitch

  • rotZ: Orientation in degrees (rotation about the Z axis),方向角Yaw

  • magX, magY, magZ: Magnetometer readings (AR-Drone 2.0 Only) (TBA: Convention),磁场传感器

  • pressure: Pressure sensed by Drone’s barometer (AR-Drone 2.0 Only) (Pa), 气压

  • temp : Temperature sensed by Drone’s sensor (AR-Drone 2.0 Only) (TBA: Unit), 温度

  • wind_speed: Estimated wind speed (AR-Drone 2.0 Only) (TBA: Unit), 风速

  • wind_angle: Estimated wind angle (AR-Drone 2.0 Only) (TBA: Unit), 风向角

  • wind_comp_angle: Estimated wind angle compensation (AR-Drone 2.0 Only) (TBA: Unit)

  • altd: Estimated altitude (mm), 预测的当前高度

  • motor1..4: Motor PWM values, 电机PWM控制值

  • vx, vy, vz: Linear velocity (mm/s) [TBA: Convention], 当前线性速度

  • ax, ay, az: Linear acceleration (g) [TBA: Convention], 当前转向速度

  • tm: Timestamp of the data returned by the Drone returned as number of micro-seconds passed since Drone’s boot-up.

2) Cameras,前置摄像头和底部摄像头的视频流分别位于ardrone/front/image_raw 和 ardrone/bottom/image_raw,传输使用标准的ROS camera interface接口。同时摄像头可以通过ardrone_front.yaml和ardrone_bottom.yaml这两个配置文件进行校正;

3) 飞行器控制 (输入),位于cmd_vel,该节点接受geometry_msgs::Twist 数据作为输入,可以控制飞行器在x, y, z上的速度,以及控制yaw的角速度:

-linear.x: move backward
+linear.x: move forward
-linear.y: move right
+linear.y: move left
-linear.z: move down
+linear.z: move up

-angular.z: turn left
+angular.z: turn right

用户开发自己的Node程序时,只要在程序中Publish或者Subscribe上述对应的topics,就可以和AR.Drone双向通信了。ROS的开发编程方法在此不再赘述,但是推荐使用C++的API(另一个为python接口,觉得支持的还不好)。

目前先写这么多,如果还收到其他开发上的疑问,我再进行补充。最后附上ardrone_autonomy的在线手册地址

AR.Drone Position Servoing and Visual Tracking

A demonstration of my Master’s Thesis: Visual-Based Localization and Tracking of a UGV with a Quadcopter. In this project, a visual tracking framework is designed to track the UGV with an AR.Drone quadcopter from Parrot. The system utilizes a centralized control by a ground station which is running ROS and Ubuntu 12.04 LTS.

The first two experiments were taken with the support of a global vision system which was designed using a low cost web camera. While in the last experiment, the quadcopter simply uses IMU data for navigation. The image was captured from the bottom camera of the AR.Drone and processed with OpenCV. Four PID controllers were designed to control the motion of the quadcopter to make it hold at a position or track a trajectory.

The next step is to use such a robot system for factory and infrastructure inspection. But since I have to return my quadcopter to the department, it is really problematic for me to imply this idea. Hope I can find the chance to get another AR.Drone soon.

(国内用户请访问优酷:http://v.youku.com/v_show/id_XNzczOTg0MDY0.html

ROS的消息回调处理:ros::spin()与ros::spinOnce()

作者注:本文基于ROS Hydro,新版本可能存在细微差别,以官方资料为准。

我们知道ROS的主循环中需要不断调用ros::spin() 或 ros::spinOnce(),两者区别在于前者调用后不会再返回,而后者在调用后还可以继续执行之后的程序。

在使用ros::spin()的情况下,一般来说在初始化时已经设置好所有消息的回调,并且不需要其他背景程序运行。这样以来,每次消息到达时会执行用户的回调函数进行操作,相当于程序是消息事件驱动的;而在使用ros::spinOnce()的情况下,一般来说仅仅使用回调不足以完成任务,还需要其他辅助程序的执行:比如定时任务、数据处理、用户界面等。

关于消息接收回调机制在ROS官网上略有说明 (callbacks and spinning)。总体来说其原理是这样的:除了用户的主程序以外,ROS的socket连接控制进程会在后台接收订阅的消息,所有接收到的消息并不是立即处理,而是等到spin()或者spinOnce()执行时才集中处理。所以为了保证消息可以正常接收,需要尤其注意spinOnce()函数的使用 (对于spin()来说则不涉及太多的人为因素)。

I. 对于速度较快的消息,需要注意合理控制消息队列及spinOnce()的时间。例如,如果消息到达的频率是100Hz,而spinOnce()的执行频率是10Hz,那么就要至少保证消息队列中预留的大小大于10。

II. 如果对于用户自己的周期性任务,最好和spinOnce()并列调用。即使该任务是周期性的对于数据进行处理,例如对接收到的IMU数据进行Kalman滤波,也不建议直接放在回调函数中:因为存在通信接收的不确定性,不能保证该回调执行在时间上的稳定性。

// 示例代码
ros::Rate r(100);

while (ros::ok())
{
  libusb_handle_events_timeout(...); // Handle USB events
  ros::spinOnce();                   // Handle ROS events
  r.sleep();
}

III. 最后说明一下将ROS集成到其他程序架构时的情况。有些图形处理程序会将main()包裹起来,此时就需要找到一个合理的位置调用ros::spinOnce()。比如对于OpenGL来说,其中有一个方法就是采用设置定时器定时调用的方法:

// 示例代码
void timerCb(int value) {
  ros::spinOnce();
}

glutTimerFunc(10, timerCb, 0);
glutMainLoop(); // Never returns

所以要想对一个系统架构游刃有余,必须了解底层API的基本运作形式,否则整个程序漏洞百出,自然不能按照预期执行。

【参考资料】

[1] wiki.ROS.org, “Significance of ros::spinOnce()”,http://answers.ros.org/question/11887/significance-of-rosspinonce/

ROS Hydro安装教程

ROS (Robot Operating System) 是目前最为领先的机器人操作系统,被广泛用于机器人系统的控制与仿真中。虽然之前早有了解,但直到近日因为科研需要才开始正式使用它。ROS目前由Willow Garage维护,最新的版本为ROS Hydro,支持最好的平台为Linux Ubuntu 12.04。

Hydromedusa_web1

ROS Hydro的安装过程并不复杂,按照特定步骤一般不会有什么问题,20 – 30分钟左右就可以安装完成。以下为完整的安装步骤:

1. 配置安装环境

1.1 安装Ubuntu 12.04

可以直接安装到硬盘或者安装到虚拟机中。因为ROS对计算机的资源消耗较大,为了提高性能,推荐直接安装至硬盘。

1.2 打开Ubuntu软件安装权限

运行软件中心->编辑->选择软件源,确认 “restricted,” “universe,” “multiverse.”处于勾选状态。

1.3 修改source.list文件

为了下载ROS安装包,需要增加对packages.ros.org安装源的支持:

sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu precise main" > /etc/apt/sources.list.d/ros-latest.list'

1.4 设置密钥

wget https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -O - | sudo apt-key add -

2. 安装ROS Hydro

2.1 更新安装源apt-install update

sudo apt-get update

2.2 安装ROS Hydro完全版

推荐使用完全安装的方式,包含ROS主程序、2D/3D仿真器、可视化工具、导航与传感程序栈:

sudo apt-get install ros-hydro-desktop-full

安装时间较长,网络情况较好的情况下10分钟左右可以完成。

3. 安装依赖包和工具

3.1 初始化rosdep

rosdep是ROS解决程序包依赖的工具:

sudo rosdep init
rosdep update

3.2 环境变量设置

可以直接将ROS初始化脚本插入到~/.bashrc中,也可每次启动时单独source一遍:

echo "source /opt/ros/hydro/setup.bash" >> ~/.bashrc

或者每次启动时输入:

source /opt/ros/hydro/setup.bash

3.3 安装rosinstall

rosinstall是ROS下载程序包集合的工具,安装方法:

sudo apt-get install python-rosinstall

至此,ROS就全部安装完成了。最后检验一下ROS是否安装正确,打开一个新的命令行,运行roscore:

roscore

【参考资料】

[1] ROS.org, Ubuntu install of ROS Hydro, http://wiki.ros.org/hydro/Installation/Ubuntu