在这里分享了运动规划方面的一些基本的算法原理和伪代码实现,其中内容可能存在不完善和错误之处,如有读者发现,欢迎批评指正。
# 方法一:view_frames工具
rosrun tf view_frames
# 方法二:rqt
rosrun rqt_tf_tree rqt_tf_tree
# ros2
sudo apt install ros-foxy-tf2-tools
ros2 run tf2_tools view_frames.py
# 变换关系
rosrun tf tf_echo /world /turtle1
# 时间延迟
rosrun tf tf_monitor /world /turtle1
std_msgs/Header header
uint32 seq
time stamp
string frame_id
string child_frame_id
geometry_msgs/Transform transform
geometry_msgs/Vector3 translation
float64 x
float64 y
float64 z
geometry_msgs/Quaternion rotation
float64 x
float64 y
float64 z
float64 w
广播静态坐标转换
广播器:tf2_ros::StaticTransformBroadcaster
广播方法:tf2_ros::StaticTransformBroadcaster::sendTransform(geometry_msgs/TransformStamped)
广播动态坐标转换
广播器:tf2_ros::TransformBroadcaster
广播方法:tf2_ros::TransformBroadcaster::sendTransform(geometry_msgs/TransformStamped)
广播方法:
1、发送一个TransformStamped消息
void sendTransform (const geometry_msgs::TransformStamped &transform)
2、发送一组TransformStamped消息
void sendTransform (const std::vector< geometry_msgs::TransformStamped > &transforms)
static tf2_ros::StaticTransformBroadcaster static_br;
geometry_msgs::TransformStamped static_tfStamped;
static_tfStamped.header.stamp = ros::Time::now();
static_tfStamped.header.frame_id = "parent_frame";
static_tfStamped.child_frame_id = "child_frame";
static_tfStamped.transform.translation.x = atof(x);
static_tfStamped.transform.translation.y = atof(y);
static_tfStamped.transform.translation.z = atof(z);
tf2::Quaternion quat;
quat.setRPY(atof(wx), atof(wy), atof(wz);
static_tfStamped.transform.rotation.x = quat.x();
static_tfStamped.transform.rotation.y = quat.y();
static_tfStamped.transform.rotation.z = quat.z();
static_tfStamped.transform.rotation.w = quat.w();
static_br.sendTransform(static_tfStamped);
void callback(const xxx& msg)
{
static tf2_ros::TransformBroadcaster br;
geometry_msgs::TransformStamped tfStamped;
tfStamped.header.stamp = ros::Time::now();
tfStamped.header.frame_id = "parent_frame";
tfStamped.child_frame_id = "child_frame";
tfStamped.transform.translation.x = msg->x;
tfStamped.transform.translation.y = msg->y;
tfStamped.transform.translation.z = msg->z;
tf2::Quaternion q;
q.setRPY(msg->wx, msg->wy, msg->wz);
tfStamped.transform.rotation.x = q.x();
tfStamped.transform.rotation.y = q.y();
tfStamped.transform.rotation.z = q.z();
tfStamped.transform.rotation.w = q.w();
br.sendTransform(tfStamped);
}
监听坐标转换
监听器:tf2_ros::TransformListener
监听缓存设置
缓存器:tf2_ros::Buffer 默认10s缓存
监听方法
geometry_msgs::TransformStamped lookupTransform (const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration timeout) const
#include
tf2_ros::Buffer tfBuffer;
tf2_ros::TransformListener tfListener(tfBuffer);
try
{
transformStamped = tfBuffer.lookupTransform("turtle2", "turtle1",ros::Time(0));
}
catch (tf2::TransformException &ex)
{
ROS_WARN("%s",ex.what());
ros::Duration(1.0).sleep();
continue;
}
ubuntu20.04
roslaunch turtle_tf turtle_tf_demo.launch
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1000
https://blog.csdn.net/xiaowang_tongxue/article/details/108298544
Listening to /tf for 5.0 seconds
Done Listening
b'dot - graphviz version 2.43.0 (0)\n'
Traceback (most recent call last):
File "/opt/ros/noetic/lib/tf/view_frames", line 119, in <module>
generate(dot_graph)
File "/opt/ros/noetic/lib/tf/view_frames", line 89, in generate
m = r.search(vstr)
TypeError: cannot use a string pattern on a bytes-like object
sudo gedit /opt/ros/noetic/lib/tf/view_frames
88 print(vstr)
vstr=str(vstr) //加入这个...
89 m = r.search(vstr)