本系列文章是 2024 春季学期北航计算机学院本科生课程《软件工程》(嵌入式方向)的实验部分报告,不包含团队大作业项目内容与相关细节

任务4-机器人kinect相机使用

实验目的

  • 了解启智机器人的 Kinect2 视觉传感器,并操作传感器完成简单的图像处理任务

启智机器人头部装备一台 Kinect2 视觉传感器,可以输出图像或三维点云,从而能够进行监控、人脸识别、物体检测等行为。

实验任务

  • 开启启智机器人的 Kinect2 传感器,实现监控、人脸识别、物体检测等任务

实验内容

kinect实时监控

本项目在任务 3 的基础上继续开发。

修改原始场景

在启动原始场景的 wpb_launch.launch 文件中添加物体节点,并通过参数调整其在场景中的初始位置:

<node name="kai_standing" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/kai_standing.model -x -2 -y 0 -z 0 -Y 1.57 -urdf -model kai_standing" />

image-20240322235919545

  • 这里的节点添加了一个 kai_standing.model 的模型文件
  • 模型位置由 args 中的 -x、-y、-z 控制
$ roslaunch wpr_simulation wpb_simple.launch

使用视频传感器

首先启动机器人位移控制节点 keyboard_vel_ctrl,控制机器人的移动操作;同时启动机器人的视频传感器传输节点 demo_cv_image,能够看到传感器返回的实时录像

$ rosrun wpr_simulation keyboard_vel_ctrl
$ rosrun wpr_simulation demo_cv_image

调整机器人位置后可以获得视频的捕获画面:

image-20240323000849316

人脸识别

调整机器人模型

当前机器人的视频传感器角度过低,可以使用内置模型进行替换、或是修改 kinect_heightkinect_pitch 参数,改变其传感器角度:

<!-- Spawn a robot into Gazebo -->
<node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-file $(find wpr_simulation)/models/wpb_home_head_up.model -urdf -model wpb_home_head_up" />
<!-- 修改 kinect_pitch -->
<joint name="kinect_pitch" type="fixed">
<origin xyz="0 0 0" rpy="0 0.5 0" /> <!-- 从 0.1 调整至 0.5 -->
<parent link="kinect2_dock" />
<child link="kinect2_head_frame" />
</joint>

启动人脸检测服务

随后启动模拟的人脸检测节点 demo_cv_face_detect,但注意到级联分类器的加载出现了报错:

cookedbear@ubuntu:~/ros/task1/BUAA-SoftwareEngineering-2024-ROS-Single$ rosrun wpr_simulation demo_cv_face_detect
[ INFO] [1711124664.505208519]: demo_cv_face_detect
[ERROR] [1711124664.505448108]: fail to load haarcascade_frontalface_alt.xml

倒查源文件是 src/wpr_simulation/src/demo_cv_face_detect.cpp 后发现其中函数调用文件的方式是绝对路径,需要针对当前目录作出一定的修改:

std::string strLoadFile;
char const* home = getenv("HOME");
strLoadFile = home;
strLoadFile += "/catkin_ws"; /* 此处修改为你的工作空间目录/项目根目录 */
strLoadFile += "/src/wpr_simulation/config/haarcascade_frontalface_alt.xml";

最后再使用 catkin_make 重新编译项目,编译结束后就可以运行所有相关节点了:

$ roslaunch wpr_simulation wpb_simple.launch
$ rosrun wpr_simulation keyboard_vel_ctrl
$ rosrun wpr_simulation demo_cv_face_detect

image-20240323011042888

最终机器人将摄像机的原始图像输入转化为灰度图,并使用了 opencv 的相关函数成功完成了人脸的识别

桌面物体检测

首先进入 wpb_table.launch 文件并注释掉与本实验无关的抓取动作相关的节点,然后启动 launch 文件,该文件会启动 RViz、Gazebo 和物体识别的服务节点进行物体识别,可以通过同时运行位移控制节点来进行各个物体的检测识别

$ roslaunch wpr_simulation wpb_table.launch

演示视频点这里

机器人跟随

首先按照实验说明中的参考参数修改 src/wpr_simulation/src/demo_cv_follow.cpp 文件中的参数值:

static int iLowH = 90;
static int iHighH = 120;

static int iLowS = 25;
static int iHighS = 220;

static int iLowV = 1;
static int iHighV = 255;

然后启动 launch 文件和跟随控制节点:

$ roslaunch wpr_simulation wpb_simple.launch
$ rosrun wpr_simulation demo_cv_follow

对人物模型使用 Translation Mode 进行移动后,可以看到机器人对其颜色质心进行了追踪,并进行相关位置的调整。

image-20240323015253214

演示视频见下:

演示视频点这里

追踪思考1

  • 思考该例程如何控制机器人移动的,具体的数据流向是怎样的?

节点话题关系图如下所示:

image-20240323015544535

从图中可以看出上半幅是基础的机器人关节结构相关节点和话题;下半的左侧是相机模块发布的 /kinect2 话题,其中包含子话题 /kinect2/qhd/Image_color_rect,它根据图像传感器传递的图像数据分析颜色重心,通过 /demo_cv_follow 话题将相关的轴向/径向的移动数据发布给 /cmd_vel 话题,从而驱使机器人进行移动,最后机器人的移动操作会渲染在 /gazebo 和 GUI 上

追踪思考2

  • 注意 demo_cv_follow 的跟随效果受机器人俯仰角影响,初始的机器人模型相较于 2 人脸识别中 head_up 的机器人模型具有更好的跟随效果,结合速度计算方式思考为什么?

下面两图分别是使用初始机器人模型和 head_up 机器人模型的两个 RGB 图 + 二值化图像,可以很清晰地观察到两者的灰度质心,即右侧二值化图白色像素平均后的中心(通过 opencv 画出的蓝色十字表示)位置不同,初始模型显然距离整张图像的中点要高不少,而 head_up 模型则更靠近中心。

//计算机器人运动速度
float fVelFoward = (nImgHeight/2-nTargetY)*0.002; //差值*比例
float fVelTurn = (nImgWidth/2-nTargetX)*0.003; //差值*比例
vel_cmd.linear.x = fVelFoward;
vel_cmd.angular.z = fVelTurn;
/*
* nImgHeight: 图像 y 方向的像素总数
* nTargetY: 二值化图计算的灰度质心 y 方向坐标
*
* nImgWidth: 图像 X 方向的像素总数
* nTargetX: 二值化图计算的灰度质心 X 方向坐标
*/

因为移动速度的计算公式导出的前后径向移动速度取决于灰度质心距离图像中心的距离,又因为初始机器人通常会向下看,导致了基本只有人像的下半身会出现在图像的上半部分,这导致了初始机器人会追踪到相对更近的位置,让人物模型更多地进入屏幕的下半部分,才会通过平衡灰度质心的位置而停下;

而 head_up 的机器人整体质心的位置相对稳定,所以在距离人物模型很远的位置就会停下来,追踪的效果较差。

image-20240323020833251

image-20240323015951569