ros机器人中如何AprilTag二维码检测和定位

External Player - 哔哩哔哩嵌入式外链播放器

AprilTag简介

AprilTag类似于二维码QR codes(Quick Response Code;全称为快速响应矩阵图码)

AprilTag可用于多种用途,包括相机标定、目标大小估计单目距离测量等。

二维码可以直接用打印机打印在纸张上,不需要特殊材料。

而AprilTag检测程序可以计算相对于相机的三维位置和二维码所承载的ID信息。

参考链接:

AprilTag

apriltag_ros - ROS Wiki

使用前准备-功能包

sudo apt install ros-$ROS_DISTRO-apriltag-ros

为了方便使用,我创建了一个新的功能包用于存放相机启动、标定文件已经apriltag_ros所需要的配置文件

cd ~/catkin_ws/src
git clone https://gitee.com/bingda-robot/apriltag_detection.git

功能包中有launch、config和doc目录

doc目录

存放了tag36h11标签族的标签图像,方便直接取用

config目录

存放相机标定文件ost.yaml和apriltag_ros相关的配置文件

其中settings.yaml文件配置了apriltag检测的标签类型、使用计算机资源等,完整的参数参考wiki链接

tags.yaml文件存放所检测的标签序号、尺寸信息,这里我们设置0、1、2三个标签的信息

standalone_tags:
  [
    {id: 0, size: 0.05},
    {id: 1, size: 0.04},
    {id: 2, size: 0.03},
  ]

launch目录

camera.launch用于启动相机并载入标定参数和矫正图像,关于相机标定和图像矫正可以参考之前的文章摄像头标定--camera_calibration

使用时需要根据你实际所使用的相机标定结果替换config目录中的相机标定文件ost.yaml

<launch>

	<node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" >
		<param name="video_device" value="/dev/video0" />
		<param name="image_width" value="640" />
		<param name="image_height" value="480" />
		<param name="pixel_format" value="yuyv" />
		<param name="camera_frame_id" value="usb_cam" />
		<param name="io_method" value="mmap"/>
		<param name="camera_name" value="usb_cam"/>
		<param name="camera_info_url" value="file://$(find apriltag_detection)/config/ost.yaml"/>
	</node>

	<node name="charge_cam_image_proc" pkg="image_proc" type="image_proc" output="screen"  ns="usb_cam" />

	<node pkg="tf" type="static_transform_publisher" name="base_footprint_to_camera"
		args="-0.04 0.0 0.05 -1.57 0.0 -1.57 base_footprint usb_cam 20">
	</node>    

</launch>

continuous_detection.launch参考了apriltag_ros中的示例文件,主要修改了参数文件载入路径和相机名称

<launch>
	<arg name="launch_prefix" default="" /> <!-- set to value="gdbserver localhost:10000" for remote debugging -->
	<arg name="node_namespace" default="apriltag_ros_continuous_node" />
	<arg name="camera_name" default="/usb_cam" />
	<arg name="image_topic" default="image_rect" />

	<!-- Set parameters -->
	<rosparam command="load" file="$(find apriltag_detection)/config/settings.yaml" ns="$(arg node_namespace)" />
	<rosparam command="load" file="$(find apriltag_detection)/config/tags.yaml" ns="$(arg node_namespace)" />

	<node pkg="apriltag_ros" type="apriltag_ros_continuous_node" name="$(arg node_namespace)" clear_params="true" output="screen" launch-prefix="$(arg launch_prefix)" >
		<!-- Remap topics from those used in code to those on the ROS network -->
		<remap from="image_rect" to="$(arg camera_name)/$(arg image_topic)" />
		<remap from="camera_info" to="$(arg camera_name)/camera_info" />

		<param name="publish_tag_detections_image" type="bool" value="true" />      <!-- default: false -->
	</node>
</launch>

使用前准备-标签

将doc目录中的AprilTag_0_1_2.pdf文件按照一比一打印在A4纸上,如有条件,可以将打印后的A4纸贴在亚克力板或者硬纸板上,避免二维码因为纸张弯曲大幅度变形

运行AprilTag检测

尝试启动相机和apriltag检测程序

roslaunch apriltag_detection camera.launch
roslaunch apriltag_detection continuous_detection.launch 

打开一个rqt_image_view订阅/tag_detections_image话题,将标签纸放在相机前

检测到的标签会被白色框框出,并标注标签的值

打开rviz,将Fixed Frame设置为base_footprint,rive中会显示标签和相机坐标位置关系

tag_detections话题会输出当前检测的标签位置信息

rostopic echo /tag_detections

通过订阅tag_detections话题或者监听相机坐标相对于标签坐标之间的位置关系,就可以获得标签和相机之间的位置关系,有了这个比较准确的位置关系,可以完成目标跟踪、视觉抓取等应用。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用IMU和激光雷达进行机器人定位,可以采用扩展卡尔曼滤波(Extended Kalman Filter,EKF)算法。 首先,需要在ROS环境安装`robot_localization`功能包,可以通过以下命令进行安装: ``` sudo apt-get install ros-<distro>-robot-localization ``` 其,`<distro>`是ROS版本号,例如`kinetic`、`melodic`等。 接着,在ROS节点引入`robot_localization`的头文件,并创建一个`ros::NodeHandle`对象: ``` #include <ros/ros.h> #include <robot_localization/ekf_localization_node.hpp> ... ros::NodeHandle nh("~"); ``` 然后,需要设置EKF的参数,例如状态量、传感器数据类型等: ``` std::vector<std::string> state_vars = {"x", "y", "z", "roll", "pitch", "yaw", "xd", "yd", "zd", "rolld", "pitchd", "yawd"}; // 状态量 std::vector<std::string> odom_vars = {"x", "y", "z", "roll", "pitch", "yaw"}; // 里程计数据 std::vector<std::string> imu_vars = {"roll", "pitch", "yaw", "rolld", "pitchd", "yawd"}; // IMU数据 std::vector<std::string> laser_vars = {"x", "y", "z"}; // 激光雷达数据 robot_localization::EkfLocalizationNode::EkfConfig config; config.set_state_vars(state_vars); config.set_odom_vars(odom_vars); config.set_imu_vars(imu_vars); config.set_laser_vars(laser_vars); ``` 接着,可以通过以下代码创建EKF节点: ``` robot_localization::EkfLocalizationNode ekf_node(config); ekf_node.setNodeHandle(&nh); ekf_node.init(); ``` 最后,可以在`ros::spin()`循环调用EKF节点的定位函数,例如: ``` while (ros::ok()) { ekf_node.correct(); // 使用IMU和激光雷达数据进行校正 pose = ekf_node.getRobotPose(); // 获取机器人位姿 ... ros::spinOnce(); } ``` 这样就可以使用C++编写ROS机器人使用IMU和激光雷达进行定位了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值