ROS:坐标管理系统

一、机器人中的坐标变换

机器人运动学的核心,描述任意两个坐标系之中任意两个向量之间的变换,可以用一个4×4的变换矩阵(Transformation Matrices)来描述它的平移和旋转变化。
变换矩阵中有包括旋转矩阵(Rotation Matrix)的信息和位置移动(Translation)的信息。
在这里插入图片描述

二、TF功能包

2.1TF功能包简介

一个机器人中,可以有很多坐标系,我们需要去描述任意两个坐标系之间的关系,涉及到大量的矩阵运算。我们可以用ROS中的TF(Transform)功能包来解决问题。
在这里插入图片描述
TF功能包的特点:默认能记录10秒内机器人所有坐标系之间的位置关系。
如:
5秒钟之前,机器人头部坐标系相对于全局坐标系的关系是什么样的?
机器人夹取的物体相对于机器人中心坐标系的位置在哪里?
机器人中心坐标系相对于全局坐标系的位置在哪里?

2.2TF坐标变换实现

实现机制:
广播TF变换
监听TF变换

这有别于之前topic和service的机制。
在ROS Master启动后,启动TF后,会在后台维护一个名为“TF树(TF Tree)”的数据结构。所有的坐标系都是通过树形结构保存在这个树结构当中,当有结点想查询某两个坐标系之间的关系的话,直接可以查询这个TF Tree来得到。

2.3TF案例

在这里插入图片描述
比如这辆带激光雷达的车,车体是以base_link为坐标系的,激光雷达是以base_laser为坐标系的,可以看到base_laser是base_link向x轴平移了0.1m,向z轴平移了0.2m,y轴没有平移。
当base_laser测到离墙面的距离为0.3m,即向量(0.3,0,0)时,就可以根据图下方的TF tree进行坐标系之间的数据变换的运算,从而算出base_link的相对与测距点的相对向量(0.4,0,0.2)。

三、小海龟跟随实验

3.1打开小程序

roslaunch turtle_tf turtle_tf_demo.launch

注:第一次运行可能会报错
报错的原因可能是Python解释器的指向问题。
打开终端依次输入:

cd /usr/bin/
sudo rm -r python
sudo cp python3 python

在这里插入图片描述
打开后就会有两只海龟,直接用键盘操作一只海龟前进,另一只会跟过来。
在这里插入图片描述

3.2查看当前的TF树

查看当前的TF tree,查看一下坐标系之间的关系。

rosrun tf view_frames

在这里插入图片描述
注:noetic直接运行可能会报错,无法生成pdf文件。解决方案:
先打开它指向的那个view_frames文件的修改权限:

sudo chmod a+w /opt/ros/noetic/lib/tf/view_frames

打开,88行后加上

vstr = str(vstr)

在这里插入图片描述
加上后重新运行。
可在用户文件夹下生成一个pdf文件:
在这里插入图片描述

可以看到有3个坐标系,除了两个海龟自身的坐标系,还有个world坐标系。
这颗TF树展示了当前的坐标间的位置关系,turtle1和turtle2是相对world坐标系变化的。
在这里插入图片描述

3.3坐标相对位置关系可视化1(tf_echo)

想看两个海龟的相对变换关系,输入:

rosrun tf tf_echo turtle1 turtle2

在这里插入图片描述
我们接着操控海龟1移动,相对关系就发生了变化:
在这里插入图片描述
这里包含了Translation和Rotation的信息。
Translation表示了相对位移的信息(是一个3×1的向量)。
Rotation表示了旋转矩阵的信息(一个3×3的矩阵,但自由度为3),它又有两种表示方式:
1.RPY表示法(pitch俯仰角、yaw偏航角、roll翻滚角)
2.四元数法(Quaternion)
都可以表示旋转矩阵的信息

Rotation和Translation合起来可以构成变换矩阵

3.4坐标相对位置关系可视化2(rviz)

rviz命令

rosrun rviz rviz -d `rospack find turtle_tf` /rviz/turtle_rviz.rviz

在这里插入图片描述
打开rviz界面。
上面Fixed Frame选 world。Add选添加TF,可以看到3个坐标系了。
在这里插入图片描述
控制海龟运动,坐标系发生改变,然后坐标系turtle2原点会靠近turtle1原点:
在这里插入图片描述
在这里插入图片描述
下图中左边变换矩阵的运算,其实就是坐标移动的本质。两个坐标系相对于world坐标系的变换的乘积可以求得两个坐标系相对的变换关系。
在这里插入图片描述
参考视屏:古月居ROS入门21讲
在这里插入图片描述

#include <ros/ros.h> #include <geometry_msgs/PoseStamped.h> #include <mavros_msgs/CommandBool.h> #include <mavros_msgs/SetMode.h> #include <mavros_msgs/State.h> #include <unistd.h> // 全局变量存储无人机状态和置 mavros_msgs::State current_state; geometry_msgs::PoseStamped current_pose; // 回调函数:更新无人机状态 void state_cb(const mavros_msgs::State::ConstPtr& msg) { current_state = *msg; } // 回调函数:更新当前置 void pose_cb(const geometry_msgs::PoseStamped::ConstPtr& msg) { current_pose = *msg; } int main(int argc, char **argv) { ros::init(argc, argv, "drone_control_node"); ros::NodeHandle nh; // 订阅无人机状态和ros::Subscriber state_sub = nh.subscribe<mavros_msgs::State>("mavros/state", 10, state_cb); ros::Subscriber pose_sub = nh.subscribe<geometry_msgs::PoseStamped>("mavros/local_position/pose", 10, pose_cb); // 发布目标ros::Publisher local_pos_pub = nh.advertise<geometry_msgs::PoseStamped>("mavros/setpoint_position/local", 10); // 服务客户端:解锁无人机和设置模式 ros::ServiceClient arming_client = nh.serviceClient<mavros_msgs::CommandBool>("mavros/cmd/arming"); ros::ServiceClient set_mode_client = nh.serviceClient<mavros_msgs::SetMode>("mavros/set_mode"); // 等待MAVROS与飞控连接 while (ros::ok() && !current_state.connected) { ros::spinOnce(); ros::Duration(0.1).sleep(); } // 设置目标高度为8米(ENU坐标系,Z轴向上) geometry_msgs::PoseStamped target_pose; target_pose.pose.position.x = 0; target_pose.pose.position.y = 0; target_pose.pose.position.z = 8.0; // 目标高度 // 先发送若干目标点,激活Offboard模式 for (int i = 100; ros::ok() && i > 0; --i) { local_pos_pub.publish(target_pose); ros::spinOnce(); ros::Duration(0.01).sleep(); } // 设置Offboard模式 mavros_msgs::SetMode offboard_mode; offboard_mode.request.custom_mode = "OFFBOARD"; // 解锁无人机 mavros_msgs::CommandBool arm_cmd; arm_cmd.request.value = true; ros::Time last_request = ros::Time::now(); // 主循环 while (ros::ok()) { // 切换Offboard模式并解锁 if (current_state.mode != "OFFBOARD" && (ros::Time::now() - last_request > ros::Duration(5.0))) { if (set_mode_client.call(offboard_mode) && offboard_mode.response.mode_sent) { ROS_INFO("Offboard enabled"); } last_request = ros::Time::now(); } else { if (!current_state.armed && (ros::Time::now() - last_request > ros::Duration(5.0))) { if (arming_client.call(arm_cmd) && arm_cmd.response.success) { ROS_INFO("Drone armed"); } last_request = ros::Time::now(); } } // 检查是否到达目标高度(允许0.1米误差) if (current_pose.pose.position.z > 7.9) { ROS_INFO("Reached 8m, hovering..."); ros::Duration(2.0).sleep(); // 悬停2秒 target_pose.pose.position.z = 0.0; // 设置降落目标 ROS_INFO("Landing..."); } // 持续发布目标置 local_pos_pub.publish(target_pose); ros::spinOnce(); ros::Duration(0.1).sleep(); } return 0; }
03-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello xiǎo lěi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值