用aruco_ros订阅位姿

求问aruco使用中,如何使用c++通过aruco_ros包中的aruco_ros/Markerarray.msg订阅到marker的坐标,感觉自己订阅到的不是全局坐标,也不是相对于相机的坐标,很迷

要使用C++通过aruco_ros包中的aruco_ros/Markerarray.msg订阅到marker的坐标,您需要遵循以下步骤:

  1. 确保您已经安装了ROS(Robot Operating System)和aruco_ros包。
  2. 创建一个ROS节点来订阅aruco_ros/Markerarray.msg消息。您可以使用以下命令创建一个简单的节点:
#include <ros/ros.h>
#include <aruco_ros/Markerarray.h>

void markerCallback(const aruco_ros::Markerarray::ConstPtr& msg) {
  // 处理marker坐标的代码
}

int main(int argc, char** argv) {
  ros::init(argc, argv, "marker_subscriber");
  ros::NodeHandle nh;

  ros::Subscriber sub = nh.subscribe("marker_array", 1000, markerCallback);

  ros::spin();

  return 0;
}

在上述代码中,我们首先包含所需的头文件,然后创建了一个名为"marker_subscriber"的节点。在主函数中,我们使用ros::NodeHandle创建了一个节点句柄,并使用ros::subscribe函数订阅了名为"marker_array"的主题。在回调函数markerCallback中,您可以处理接收到的marker坐标。
3. 编译并运行您的节点。您可以使用以下命令编译ROS节点:

$ roscd aruco_ros
$ cd ../../..
$ catkin_make

然后,通过以下命令运行您的节点:

$ rosrun marker_subscriber marker_subscriber.cpp

请确保将"marker_subscriber.cpp"替换为您实际的节点名称。
4. 在您的代码中处理接收到的marker坐标。在回调函数markerCallback中,您可以访问接收到的aruco_ros/Markerarray消息,并从中提取marker的坐标信息。具体的处理方式取决于您对aruco的使用和需求。

TechWhizKid参考GPT回答:

使用aruco_ros订阅marker坐标的方法如下:

  1. 包含头文件
#include <aruco_ros/aruco_ros_utils.h>
#include <aruco_ros/MarkerArray.h>
  1. 声明订阅者
ros::Subscriber sub;
  1. 订阅回调函数
void markerCallback(const aruco_ros::MarkerArray::ConstPtr& msg) {
  for (int i = 0; i < msg->markers.size(); ++i) {
    geometry_msgs::Pose pose = msg->markers[i].pose.pose;
    // pose包含marker的位姿信息
  }
}
  1. 初始化订阅者
sub = n.subscribe("/aruco_marker_publisher/markers", 1, markerCallback);

Marker的位姿默认是发布在相机坐标系下的,所以需要根据应用场景进行坐标转换,转换到全局坐标或其他坐标系。

aruco_ros提供了一些坐标转换的工具函数,可以在callback函数中调用,例如:

aruco_ros::transformPoseToFrame(pose, "camera_frame", "global_frame");

这样可以获得全局坐标下的marker位姿。

所以订阅到的并不是全局坐标,需要根据使用场景转换坐标系。

在使用aruco_ros包中的aruco_ros/MarkerArray消息订阅到marker的坐标时,它提供的是marker的相对坐标信息,而不是全局坐标或相对于相机的坐标。

具体来说,aruco_ros/MarkerArray消息中的每个marker都包含了以下信息:

  • header: 该marker消息的头部信息,其中包含时间戳和坐标系信息。
  • markers: 一个marker数组,每个marker包含了以下信息:
    • header: marker消息的头部信息,包含时间戳和坐标系信息。
    • id: marker的ID。
    • pose: marker在相机坐标系下的位置信息,包括位置的(x, y, z)和方向的(x, y, z, w)。

要获取全局坐标或相对于相机的坐标,需要考虑到以下几点:

  1. 数据类型转换:订阅到的marker坐标以ROS消息的形式提供,可以使用ROS API中提供的工具函数将其转换为适合在C++中操作的数据类型。
  2. 坐标系转换:相机的坐标系与全局坐标系之间可能存在差异,需要对marker的相对坐标进行坐标系转换,以获得全局或相对相机的坐标。
  3. 参数配置:确保相机和marker的参数配置正确,包括相机的内参和畸变参数以及marker的尺寸参数等。

下面是一个简单的示例代码,通过aruco_ros包中的aruco_ros/MarkerArray消息获取到marker的坐标:

#include <ros/ros.h>
#include <aruco_msgs/MarkerArray.h>

void markerArrayCallback(const aruco_msgs::MarkerArray::ConstPtr& msg)
{
    for (const auto& marker : msg->markers)
    {
        // 获取marker的ID
        int id = marker.id;
        
        // 获取marker在相机坐标系下的位置信息
        geometry_msgs::Pose pose = marker.pose;
        
        // 在这里进行坐标系转换或其他处理
        // ...
        
        // 打印marker的信息
        ROS_INFO("Marker ID: %d", id);
        ROS_INFO("Marker Pose: x=%f, y=%f, z=%f", pose.position.x, pose.position.y, pose.position.z);
    }
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "marker_subscriber");
    ros::NodeHandle nh;

    ros::Subscriber sub = nh.subscribe<aruco_msgs::MarkerArray>("/your_topic_name", 10, markerArrayCallback);

    ros::spin();

    return 0;
}

在代码中,替换/your_topic_name为你订阅aruco_ros/MarkerArray消息的实际话题名称。然后在回调函数markerArrayCallback()中,可以通过msg->markers访问到接收到的marker信息,并进行进一步的处理。

根据需求进行坐标系转换或其他处理,以获取到全局坐标或相对相机的坐标。如果有需要,可能还需要参考aruco库的文档或aruco_ros包的源代码,需要了解更多关于坐标系和参数配置的详细信息。

确保你理解你订阅到的坐标是相对于哪个坐标系定义的。如果你期望获得全局坐标,你可能需要将相机坐标系下的坐标转换到全局坐标系。这通常涉及到使用相机到全局坐标系的坐标变换矩阵(例如TF变换)来执行坐标系转换。