geometry_msgs/PoseStamped 类型的变量的构造

本文详细探讨了ROS消息类型geometry_msgs/PoseStamped的构造,引用了官方文档和相关资源,包括其在python和C/C++中的使用,并提供了相关链接以便深入理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

#navpoint.msg
geometry_msgs/PoseStamped target_pose
uint8 floor
uint8 type


target_pose 的类型为geometry_msgs/PoseStamped 

# A Pose with reference coordinate frame and timestamp
Header header
Pose pose

Record PoseStamped := { _header : Header.Header; _pose : Pose.Pose}.

简单构造

demo1
#构造header
target_pose.header.seq = 0;
target_pose.header.stamp =ros::Time::now();//如果有问题就使用Time(0)获取时间戳,确保类型一致
target_pose.header.frame_id = "map";
#构造pose
target_pose.pose.position.x 
//相关头文件包含 #include <ros/ros.h> #include <geometry_msgs/PoseStamped.h> #include <mavros_msgs/CommandBool.h> #include <mavros_msgs/SetMode.h> #include <mavros_msgs/State.h> mavros_msgs::State current_state; //回调函数 void state_cb(const mavros_msgs::State::ConstPtr& msg){ current_state = *msg; } int main(int argc, char **argv) { //初始化节点 ros::init(argc, argv, "offb_node"); //创建节点句柄 ros::NodeHandle nh; //创建订阅者,订阅话题mavros/state ros::Subscriber state_sub = nh.subscribe<mavros_msgs::State> ("mavros/state", 10, state_cb); //创建一个发布者,发布"mavros/setpoint_position/local"话题 ros::Publisher local_pos_pub = nh.advertise<geometry_msgs::PoseStamped> ("mavros/setpoint_position/local", 10); //创建一个客户端,该客户端用来请求PX4无人机的解锁 ros::ServiceClient arming_client = nh.serviceClient<mavros_msgs::CommandBool> ("mavros/cmd/arming"); //创建一个客户端,该客户端用来请求进入offboard模式 ros::ServiceClient set_mode_client = nh.serviceClient<mavros_msgs::SetMode> ("mavros/set_mode"); //搭配rate.sleep()函数,实现20Hz频率的循环; ros::Rate rate(20.0); // 等待飞控连接 while(ros::ok() && !current_state.connected){ ros::spinOnce(); rate.sleep(); } //创建一个变量,该变量是无人机即将起飞到的位置,相对于无人机上电时刻作为起始点 geometry_msgs::PoseStamped pose; pose.pose.position.x = 0; pose.pose.position.y = 0; pose.pose.position.z = 2; //预发布期望位置信息,给无人机目标点 //send a few setpoints before starting for(int i = 100; ros::ok() && i > 0; --i){ local_pos_pub.publish(pose); ros::spinOnce(); rate.sleep(); } //设置客户端请求无人机进入“OFFBOARD”模式 mavros_msgs::SetMode offb_set_mode; offb_set_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()){ //if语句循环请求进入OFFBOARD模式,进入以后则会进入else语句请求对无人机解锁。 if( current_state.mode
03-24
#include <ros/ros.h> #include <geometry_msgs/PoseStamped.h> #include <mavros_msgs/State.h> #include <mavros_msgs/PositionTarget.h> #include <mavros_msgs/CommandBool.h> #include <mavros_msgs/SetMode.h> #include <std_msgs/Bool.h> #include <cmath> // 全局变量 ros::Publisher pos_raw_pub; mavros_msgs::State current_state; geometry_msgs::PoseStamped current_pose; bool land_command_received = false; geometry_msgs::Point target_position; // 状态、位置、降落指令回调 void state_cb(const mavros_msgs::State::ConstPtr& msg) { current_state = *msg; } void pose_cb(const geometry_msgs::PoseStamped::ConstPtr& msg) { current_pose = *msg; } void landCommandCallback(const std_msgs::Bool::ConstPtr& msg) { land_command_received = msg->data; } void targetPointCallback(const geometry_msgs::Point::ConstPtr& msg) { target_position = *msg; // 更新目标点 } // 构造 PositionTarget 消息 mavros_msgs::PositionTarget makePositionTarget( float x, float y, float z, float vx, float vy, float vz, float yaw, uint16_t type_mask) { mavros_msgs::PositionTarget target; target.header.stamp = ros::Time::now(); target.coordinate_frame = mavros_msgs::PositionTarget::FRAME_LOCAL_NED; target.type_mask = type_mask; target.position.x = x; target.position.y = y; target.position.z = z; target.velocity.x = vx; target.velocity.y = vy; target.velocity.z = vz; target.yaw = yaw; return target; } // 判断是否到达目标 bool reached_target(double x, double y, double z, double threshold) { double dx = current_pose.pose.position.x - x; double dy = current_pose.pose.position.y - y; double dz = current_pose.pose.position.z - z; return (std::sqrt(dx*dx + dy*dy + dz*dz) < threshold); } int main(int argc, char **argv) { ros::init(argc, argv, "offboard_node"); ros::NodeHandle nh; // 订阅器 ros::Subscriber state_sub = nh.subscribe("mavros/state", 10, state_cb); ros::Subscriber pose_sub = nh.subscribe("mavros/local_position/pose", 100, pose_cb); ros::Subscriber land_cmd_sub = nh.subscribe("land_cmd", 1, landCommandCallback); ros::Subscriber target_cmd_sub = nh.subscribe("target_point", 1, targetPointCallback); // 发布器 pos_raw_pub = nh.advertise<mavros_msgs::PositionTarget>( "mavros/setpoint_raw/local", 100); // 服务端 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"); ros::Rate rate(100.0); ros::Rate rate_1(50.0); // 等待连接 while (ros::ok() && !current_state.connected) { ros::spinOnce(); rate.sleep(); } // 起飞前发送一些 setpoint(惯例) for (int i = 0; i < 100; ++i) { pos_raw_pub.publish(makePositionTarget( 0, 0, 1.0, 0, 0, 0, 0, mavros_msgs::PositionTarget::IGNORE_VX | mavros_msgs::PositionTarget::IGNORE_VY | mavros_msgs::PositionTarget::IGNORE_VZ | mavros_msgs::PositionTarget::IGNORE_AFX | mavros_msgs::PositionTarget::IGNORE_AFY | mavros_msgs::PositionTarget::IGNORE_AFZ | mavros_msgs::PositionTarget::IGNORE_YAW_RATE)); ros::spinOnce(); rate.sleep(); } // 设置模式并解锁 mavros_msgs::SetMode offb_set_mode; offb_set_mode.request.custom_mode = "OFFBOARD"; mavros_msgs::CommandBool arm_cmd; arm_cmd.request.value = true; ros::Time last_request = ros::Time::now(); // 等待进入 OFFBOARD 模式并解锁 while (ros::ok() && !current_state.armed) { if (current_state.mode != "OFFBOARD" && (ros::Time::now() - last_request > ros::Duration(1.0))) { if (set_mode_client.call(offb_set_mode) && offb_set_mode.response.mode_sent) { ROS_INFO("Offboard mode enabled"); } last_request = ros::Time::now(); } else if (!current_state.armed && (ros::Time::now() - last_request > ros::Duration(1.0))) { if (arming_client.call(arm_cmd) && arm_cmd.response.success) { ROS_INFO("Vehicle armed"); } last_request = ros::Time::now(); } // 上升速度控制起飞 pos_raw_pub.publish(makePositionTarget( 0, 0, 1.0, 0, 0, 0, // 向上速度 0, mavros_msgs::PositionTarget::IGNORE_VX | mavros_msgs::PositionTarget::IGNORE_VY | mavros_msgs::PositionTarget::IGNORE_AFX | mavros_msgs::PositionTarget::IGNORE_AFY | mavros_msgs::PositionTarget::IGNORE_AFZ | mavros_msgs::PositionTarget::IGNORE_YAW_RATE)); ros::spinOnce(); rate.sleep(); } ROS_INFO("Takeoff in progress..."); // === 位置误差控制飞到目标点 === double target_x = 0.0, target_y = 0.0, target_z = 1.0; target_position.x = target_x; target_position.y = target_y; target_position.z = target_z; while (ros::ok() && !reached_target(target_x, target_y, target_z, 0.1)) { pos_raw_pub.publish(makePositionTarget( target_x, target_y, target_z, 0, 0, 0.3, 0, mavros_msgs::PositionTarget::IGNORE_VX | mavros_msgs::PositionTarget::IGNORE_VY | mavros_msgs::PositionTarget::IGNORE_VZ | mavros_msgs::PositionTarget::IGNORE_AFX | mavros_msgs::PositionTarget::IGNORE_AFY | mavros_msgs::PositionTarget::IGNORE_AFZ | mavros_msgs::PositionTarget::IGNORE_YAW_RATE)); ros::spinOnce(); rate.sleep(); } ROS_INFO("Reached target. Hovering..."); bool has_landed = false; while (ros::ok() && !has_landed) { // 继续 hover /* pos_raw_pub.publish(makePositionTarget( target_x, target_y, target_z, 0, 0, 0, 0, mavros_msgs::PositionTarget::IGNORE_VX | mavros_msgs::PositionTarget::IGNORE_VY | mavros_msgs::PositionTarget::IGNORE_VZ | mavros_msgs::PositionTarget::IGNORE_AFX | mavros_msgs::PositionTarget::IGNORE_AFY | mavros_msgs::PositionTarget::IGNORE_AFZ | mavros_msgs::PositionTarget::IGNORE_YAW_RATE)); */ if(reached_target(target_position.x, target_position.y, target_position.z, 0.1)) { pos_raw_pub.publish(makePositionTarget( target_position.x, target_position.y, target_position.z, 0, 0, 0, 0, mavros_msgs::PositionTarget::IGNORE_VX | mavros_msgs::PositionTarget::IGNORE_VY | mavros_msgs::PositionTarget::IGNORE_VZ | mavros_msgs::PositionTarget::IGNORE_AFX | mavros_msgs::PositionTarget::IGNORE_AFY | mavros_msgs::PositionTarget::IGNORE_AFZ | mavros_msgs::PositionTarget::IGNORE_YAW_RATE)); } else { pos_raw_pub.publish(makePositionTarget( target_position.x, target_position.y, target_position.z, 2.0, 0, 0, 0, mavros_msgs::PositionTarget::IGNORE_VX | mavros_msgs::PositionTarget::IGNORE_VY | mavros_msgs::PositionTarget::IGNORE_VZ | mavros_msgs::PositionTarget::IGNORE_AFX | mavros_msgs::PositionTarget::IGNORE_AFY | mavros_msgs::PositionTarget::IGNORE_AFZ | mavros_msgs::PositionTarget::IGNORE_YAW_RATE)); } // 收到降落指令 if (land_command_received) { mavros_msgs::SetMode land_mode; land_mode.request.custom_mode = "AUTO.LAND"; if (set_mode_client.call(land_mode) && land_mode.response.mode_sent) { ROS_INFO("AUTO.LAND mode set"); } // 等待自动降落并 disarm(监听 current_state.armed) ros::Time land_start = ros::Time::now(); while (ros::ok()) { ros::spinOnce(); // 降落过程中不再发送 setpoint,避免干扰 if (!current_state.armed) { ROS_INFO("Landing complete. Vehicle disarmed."); break; } // 可选:设置超时 if ((ros::Time::now() - land_start).toSec() > 20.0) { ROS_WARN("Landing timeout. Attempting manual disarm..."); mavros_msgs::CommandBool disarm_cmd; disarm_cmd.request.value = false; if (arming_client.call(disarm_cmd) && disarm_cmd.response.success) { ROS_INFO("Manual disarm succeeded."); } else { ROS_WARN("Manual disarm failed."); } break; } rate.sleep(); } has_landed = true; } ros::spinOnce(); rate_1.sleep(); } return 0; } 请详细解释上述代码
最新发布
07-30
构建一个ROS2节点,需要实现以下功能:1.将LaserScan数据转换为PointCloud2(将每个激光点的距离和角度转换为笛卡尔坐标。)并发布到新话题。2.订阅该点云话题并在RViz中显示(这一步主要是用户操作,但我们需要确保发布点云话题)。3.订阅/fusion_pose话题(geometry_msgs/msg/PoseStamped类型)以获取实时位姿,并保存最新的位姿数据(用一个成员变量存储,并注意线程安全,因为回调是并发的)。4.,当收到上位机开始检测的命令时服务被调用,先回复请求已收到,然后执行货架检测算法计算货架中心位姿(需要用到最近的点云),将结果(geometry_msgs/msg/PoseStamped[2] result发给规划节点,同时发布以便在RViz中可视化。请给出详细c++代码实现与注释,可参考如下步骤-创建一个类,比如叫做ShelfDetectionNode,继承自rclpy.node.Node。-在初始化中:a.创建一个订阅者订阅/scan话题(类型sensor_msgs.msg.LaserScan),设置回调函数scan_callback。b.创建一个发布者,发布点云到/laser_pointcloud2。c.创建一个订阅者订阅/fusion_pose(类型geometry_msgs.msg.PoseStamped),回调函数pose_callback更新最新的位姿。d.创建一个服务,用于触发货架检测(服务类型需要自定义,比如example_interfaces/srv/Trigger,或者自定义一个空的服务,因为只需要触发,不需要参数。但响应部分需要先回复,然后异步处理,所以服务类型应该有一个空请求和一个立即回复的响应,然后节点再异步处理并发布结果。e.创建发布者,用于发布检测到的货架中心位姿(类型geometry_msgs.msg.PoseStamped)。注意:由于服务回调中需要执行耗时操作(货架检测),为了避免阻塞服务回调(进而阻塞ROS2的executor),我们可以在服务回调中启动一个线程来处理检测任务,或者使用异步方式。但是,ROS2的回调默认是单线程的(除非使用MultiThreadedExecutor),所以我们可以将检测任务放到另一个线程中。另一种方法是:在服务回调中,先发送响应,然后将检测任务放入一个异步任务(比如通过一个Future)或者使用一个定时器来触发后续处理。这里我们采用先发送响应,然后利用节点的executor来调度检测任务。但是,由于检测任务可能耗时,我们最好使用单独的线程处理,避免阻塞其他回调。因此,我们可以在服务回调中:-立即发送响应(表示已收到请求)。-然后,将检测任务放入一个线程池或启动一个新线程来执行检测(注意:访问共享数据如最新位姿和点云时需要加锁)。由于我们只需要存储最新的位姿和最新的点云(只保存最新的点云),所以我们可以:-在scan_callback中保存最新的点云(同样用一个成员变量存储,并加锁保护)。-在pose_callback中保存最新的位姿(加锁保护)。然后,在检测线程中,我们获取这两个数据(注意:获取时加锁,并且尽量缩短加锁时间)进行货架检测。货架检测算法用一个函数detect_shelf来表示,该函数输入是当前点云,输出是货架中心的位姿(一个PoseStamped)。最后,发布这个位姿在RViz中显示货架中心位置。
06-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值