在机器人操作系统(ROS)中,静态 TF(Transform)和动态 TF 都用于描述坐标系之间的变换关系,它们在机器人的定位、建图和感知等任务中起着关键作用。下面详细解释静态 TF 定义的坐标系变换的作用,以及动态 TF 是否会用到静态 TF 定义的关系。

静态 TF 定义的坐标系变换的作用

1. 固定传感器安装位置描述

机器人通常配备多个传感器,如激光雷达、摄像头等。这些传感器相对于机器人本体(如 base_link)的位置和姿态是固定的。通过静态 TF 可以精确描述这些固定的相对位置关系,使得不同传感器采集的数据能够统一到机器人的基坐标系下进行处理。例如,在代码中可以看到通过 static_transform_publisher 节点设置 base_linkvelodyne(激光雷达)之间的静态变换:

<node pkg="tf2_ros" type="static_transform_publisher" name="localizer_to_base_link" args="0 0 0 0 0 0 base_link velodyne"/>

这样,激光雷达采集的点云数据就可以方便地转换到 base_link 坐标系下。

2. 全局坐标系关系定义

在机器人的运行环境中,存在一些全局坐标系,如 mapworld 坐标系。这些坐标系之间的关系通常是固定的,通过静态 TF 可以定义它们之间的变换关系,为机器人的全局定位和导航提供基础。例如:

<node pkg="tf2_ros" type="static_transform_publisher" name="world_to_map" args="0 0 0 0 0 0 map world" />
3. 简化代码实现

由于静态 TF 描述的是固定的坐标系变换关系,不需要在代码中频繁更新这些变换信息,从而简化了代码的实现和维护。只需要在启动时一次性发布这些静态变换即可。

动态 TF 是否会用到静态 TF 定义的关系

动态 TF 会用到静态 TF 定义的关系。在机器人的运行过程中,动态 TF 通常描述的是随时间变化的坐标系变换,如机器人本体在地图中的位置和姿态。而静态 TF 描述的是固定的坐标系关系,这些关系是动态 TF 进行坐标转换的基础。

例如,在 ndt.cpp 文件的 callback_pointcloud 函数中,需要将激光雷达采集的点云数据从雷达坐标系(sensor_frame)转换到机器人的基坐标系(base_frame_)。首先会通过 get_transform 函数获取 base_frame_sensor_frame 之间的变换关系:

// get TF base to sensor
geometry_msgs::TransformStamped::Ptr TF_base_to_sensor_ptr(new geometry_msgs::TransformStamped);
get_transform(base_frame_, sensor_frame, TF_base_to_sensor_ptr);

这里的 base_frame_sensor_frame 之间的关系可能是通过静态 TF 定义的固定关系。然后根据这个变换关系,将点云数据从雷达坐标系转换到基坐标系:

const Eigen::Affine3d base_to_sensor_affine = tf2::transformToEigen(*TF_base_to_sensor_ptr);
const Eigen::Matrix4f base_to_sensor_matrix = base_to_sensor_affine.matrix().cast<float>();

boost::shared_ptr<pcl::PointCloud<pcl::PointXYZ>> sensor_points_baselinkTF_ptr(
  new pcl::PointCloud<pcl::PointXYZ>);
pcl::transformPointCloud(
  *sensor_points_sensorTF_ptr, *sensor_points_baselinkTF_ptr, base_to_sensor_matrix);

因此,动态 TF 在进行坐标转换时,会依赖于静态 TF 定义的固定坐标系关系,将不同坐标系下的数据统一到一个共同的坐标系中进行处理。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐