ROS系列——mavros功能包中常用话题和服务介绍,包括消息名称、类型、头文件、成员变量、示例代码

本文详细介绍了ROS Mavros功能包中的关键话题,如系统状态、GPS数据、位置控制、遥控器输入等,以及发布服务如控制位置、模式切换。通过实例代码帮助理解如何操作和使用这些功能进行无人机控制。

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

官方链接

  1. mavros
  2. mavlink功能包
  3. mavros功能包

常用话题

订阅

1.1 系统状态

消息名称:mavros/state
类型:mavros_msgs::State
头文件:mavros_msgs/State.h
成员变量:

string MODE_PX4_MANUAL=MANUAL //这里只列PX4的,APM的用rosmsg show mavros_msgs/State查看
string MODE_PX4_ACRO=ACRO
string MODE_PX4_ALTITUDE=ALTCTL
string MODE_PX4_POSITION=POSCTL
string MODE_PX4_OFFBOARD=OFFBOARD
string MODE_PX4_STABILIZED=STABILIZED
string MODE_PX4_RATTITUDE=RATTITUDE
string MODE_PX4_MISSION=AUTO.MISSION
string MODE_PX4_LOITER=AUTO.LOITER
string MODE_PX4_RTL=AUTO.RTL
string MODE_PX4_LAND=AUTO.LAND
string MODE_PX4_RTGS=AUTO.RTGS
string MODE_PX4_READY=AUTO.READY
string MODE_PX4_TAKEOFF=AUTO.TAKEOFF
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
bool connected //是否连接
bool armed //是否解锁
bool guided
bool manual_input
string mode //当前飞行模式
uint8 system_status //系统状态

1.2 GPS数据

消息名称:mavros/global_position/global
类型:sensor_msgs::NavSatFix
头文件:sensor_msgs/NavSatFix.h
成员变量:

uint8 COVARIANCE_TYPE_UNKNOWN=0
uint8 COVARIANCE_TYPE_APPROXIMATED=1
uint8 COVARIANCE_TYPE_DIAGONAL_KNOWN=2
uint8 COVARIANCE_TYPE_KNOWN=3
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
sensor_msgs/NavSatStatus status
  int8 STATUS_NO_FIX=-1
  int8 STATUS_FIX=0
  int8 STATUS_SBAS_FIX=1
  int8 STATUS_GBAS_FIX=2
  uint16 SERVICE_GPS=1
  uint16 SERVICE_GLONASS=2
  uint16 SERVICE_COMPASS=4
  uint16 SERVICE_GALILEO=8
  int8 status
  uint16 service
float64 latitude
float64 longitude
float64 altitude
float64[9] position_covariance
uint8 position_covariance_type

1.3 本地位置

消息名称:mavros/local_position/pose
类型:geometry_msgs::PoseStamped
头文件:geometry_msgs/PoseStamped.h
成员变量:

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
geometry_msgs/Pose pose
  geometry_msgs/Point position
    float64 x
    float64 y
    float64 z
  geometry_msgs/Quaternion orientation
    float64 x
    float64 y
    float64 z
    float64 w

1.4 三轴速度

消息名称:mavros/local_position/velocity
类型:geometry_msgs::TwistStamped
头文件:geometry_msgs/TwistStamped.h
成员变量:

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
geometry_msgs/Twist twist
  geometry_msgs/Vector3 linear
    float64 x
    float64 y
    float64 z
  geometry_msgs/Vector3 angular
    float64 x
    float64 y
    float64 z

1.5 IMU原始数据

消息名称:mavros/imu/data(_raw) //data_raw为原始数据,data为滤波后的数据
类型:sensor_msgs::Imu
头文件:sensor_msgs/Imu.h
成员变量:

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
geometry_msgs/Quaternion orientation
  float64 x
  float64 y
  float64 z
  float64 w
float64[9] orientation_covariance
geometry_msgs/Vector3 angular_velocity
  float64 x
  float64 y
  float64 z
float64[9] angular_velocity_covariance
geometry_msgs/Vector3 linear_acceleration
  float64 x
  float64 y
  float64 z
float64[9] linear_acceleration_covariance

1.6 遥控器数据

消息名称:mavros/manual_control/control
类型:mavros_msgs::ManualControl
头文件:mavros_msgs/ManualControl.h
成员变量:

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
float32 x
float32 y
float32 z
float32 r
uint16 buttons

1.7 waypoint 查询航点

消息名称:mavros/mission/waypoints
类型:mavros_msgs::WaypointList
头文件:mavros_msgs/WaypointList.h
成员变量:

uint16 current_seq
mavros_msgs/Waypoint[] waypoints
  uint8 FRAME_GLOBAL=0
  uint8 FRAME_LOCAL_NED=1
  uint8 FRAME_MISSION=2
  uint8 FRAME_GLOBAL_REL_ALT=3
  uint8 FRAME_LOCAL_ENU=4
  uint8 frame //坐标系  3:经纬度为绝对,高度为相对(起飞点为0)
  uint16 command //命令id  16:航点
  bool is_current
  bool autocontinue
  float32 param1
  float32 param2
  float32 param3
  float32 param4
  float64 x_lat
  float64 y_long
  float64 z_alt

发布

2.1 控制期望的位置(GPS 坐标)

2.1.1 mavros/setpoint_raw/global

消息名称:mavros/setpoint_raw/global
类型:mavros_msgs::GlobalPositionTarget
头文件:mavros_msgs/GlobalPositionTarget.h
成员变量:
血的教训:coordinate_frame设置成5时,使用的altitude为amsl高度,从/mavros/altitude中的amsl可以读到

uint8 FRAME_GLOBAL_INT=5
uint8 FRAME_GLOBAL_REL_ALT=6
uint8 FRAME_GLOBAL_TERRAIN_ALT=11
uint16 IGNORE_LATITUDE=1 //只想控制经纬高则设置type_mask=8+16+32+64+128+256+512+1024+2048
uint16 IGNORE_LONGITUDE=2
uint16 IGNORE_ALTITUDE=4
uint16 IGNORE_VX=8 //只想控制速度则设置type_mask=1+2+4+64+128+256+512+1024+2048
uint16 IGNORE_VY=16
uint16 IGNORE_VZ=32
uint16 IGNORE_AFX=64 //只想控制加速度则设置type_mask=1+2+4+8+16+32+512+1024+2048
uint16 IGNORE_AFY=128
uint16 IGNORE_AFZ=256
uint16 FORCE=512 //Force in af vector flag
uint16 IGNORE_YAW=1024
uint16 IGNORE_YAW_RATE=2048
std_msgs/Header header
  uint32 seq
  time stamp //发布消息前一定要令消息的header.stamp=ros::TIme::now()否则无人机不会运动
  string frame_id
uint8 coordinate_frame //5 为绝对amsl高度,6 为相对amsl高度
uint16 type_mask //用于确定控制哪些量
float64 latitude //经纬高
float64 longitude
float32 altitude //in meters, AMSL or above terrain
geometry_msgs/Vector3 velocity //速度
  float64 x
  float64 y
  float64 z
geometry_msgs/Vector3 acceleration_or_force //加速度
  float64 x
  float64 y
  float64 z
float32 yaw //偏航
float32 yaw_rate //偏航角速度
2.1.2 mavros/setpoint_position/global

消息名称:mavros/setpoint_position/global
类型:geographic_msgs::GeoPoseStamped
头文件:geographic_msgs/GeoPoseStamped.h
成员变量:

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
geographic_msgs/GeoPose pose
  geographic_msgs/GeoPoint position
    float64 latitude
    float64 longitude
    float64 altitude
  geometry_msgs/Quaternion orientation
    float64 x
    float64 y
    float64 z
    float64 w

2.2 控制期望的位置

消息名称:mavros/setpoint_position/local
类型:geometry_msgs::PoseStamped
头文件:geometry_msgs/PoseStamped.h
成员变量:

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
geometry_msgs/Pose pose //NED 坐标系下的位置(xyz),只有 position 成员变量生效
  geometry_msgs/Point position
    float64 x
    float64 y
    float64 z
  geometry_msgs/Quaternion orientation
    float64 x
    float64 y
    float64 z
    float64 w

2.3 控制期望的速度

消息名称:mavros/setpoint_velocity/cmd_vel_unstamped
类型:geometry_msgs::Twist
头文件:geometry_msgs/Twist.h
成员变量:

geometry_msgs/Vector3 linear //三轴线速度
  float64 x
  float64 y
  float64 z
geometry_msgs/Vector3 angular //三轴角速度
  float64 x
  float64 y
  float64 z

2.4 控制期望的加速度

消息名称:mavros/setpoint_accel/accel
类型:geometry_msgs::Vector3Stamped
头文件:geometry_msgs/Vector3Stamped.h
成员变量:

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
geometry_msgs/Vector3 vector //三轴加速度
  float64 x
  float64 y
  float64 z

2.5 控制期望的姿态

消息名称:mavros/setpoint_attitude/attitude
类型:geometry_msgs::PoseStamped
头文件:geometry_msgs/PoseStamped.h
成员变量:

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
geometry_msgs/Pose pose //三个欧拉角,或者 4 元数任选其一
  geometry_msgs/Point position
    float64 x
    float64 y
    float64 z
  geometry_msgs/Quaternion orientation
    float64 x
    float64 y
    float64 z
    float64 w

2.6 控制飞控 IO 输出(混控器)

消息名称:mavros/actuator_control
类型:mavros_msgs::ActuatorControl
头文件:mavros_msgs/ActuatorControl.h
成员变量:

uint8 PX4_MIX_FLIGHT_CONTROL=0
uint8 PX4_MIX_FLIGHT_CONTROL_VTOL_ALT=1
uint8 PX4_MIX_PAYLOAD=2
uint8 PX4_MIX_MANUAL_PASSTHROUGH=3
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
uint8 group_mix //要控制的混控器分组 1-8(control group)
float32[8] controls //控制量(前四个分别是,roll pitch yaw thrust)

常用服务

3.1 上/解锁服务

消息名称:mavros/cmd/arming
类型:mavros_msgs::CommandBool
头文件:mavros_msgs/CommandBool.h
请求参数:

bool value //true解锁 false上锁
---
bool success
uint8 result //错误信息

示例代码:

ros::ServiceClient arming_client = nh.serviceClient<mavros_msgs::CommandBool>("mavros/cmd/arming");
mavros_msgs::CommandBool arm_cmd;
arm_cmd.request.value = true;
set_mode_client.call(arm_cmd);
if(arm_cmd.response.success)
    ROS_INFO("Vehicle armed");
arm_cmd.response.result

3.2 模式切换

!!!!!!!!!!真实环境测试时不要用软件切换offboard模式!!!!!!!!!!
特别是像例程那样反复在while循环中设置offboard模式,要是控制不了机载电脑关闭该节点的话飞机就永远保持offboard模式了,如果发出的还是速度指令的话就可能会发生事故。
所以设置电子围栏也很重要。

消息名称:mavros/set_mode
类型:mavros_msgs::SetMode
头文件:mavros_msgs/SetMode.h
请求参数:

uint8 MAV_MODE_PREFLIGHT=0
uint8 MAV_MODE_STABILIZE_DISARMED=80
uint8 MAV_MODE_STABILIZE_ARMED=208
uint8 MAV_MODE_MANUAL_DISARMED=64
uint8 MAV_MODE_MANUAL_ARMED=192
uint8 MAV_MODE_GUIDED_DISARMED=88
uint8 MAV_MODE_GUIDED_ARMED=216
uint8 MAV_MODE_AUTO_DISARMED=92
uint8 MAV_MODE_AUTO_ARMED=220
uint8 MAV_MODE_TEST_DISARMED=66
uint8 MAV_MODE_TEST_ARMED=194
uint8 base_mode //基本模式,若customs_mode非空,则无效
string custom_mode //可用的模式见mavros/mavros/src/lib/uas_stringify.cpp中的px4(如果用的是APM就搜APM)
---
bool mode_sent //true表示正确切换模式

以下为PX4可用的飞行模式

static const cmode_map px4_cmode_map{{
    { px4::define_mode(px4::custom_mode::MAIN_MODE_MANUAL),           "MANUAL" },
	{ px4::define_mode(px4::custom_mode::MAIN_MODE_ACRO),             "ACRO" },
	{ px4::define_mode(px4::custom_mode::MAIN_MODE_ALTCTL),           "ALTCTL" },
	{ px4::define_mode(px4::custom_mode::MAIN_MODE_POSCTL),           "POSCTL" },
	{ px4::define_mode(px4::custom_mode::MAIN_MODE_OFFBOARD),         "OFFBOARD" },
	{ px4::define_mode(px4::custom_mode::MAIN_MODE_STABILIZED),       "STABILIZED" },
	{ px4::define_mode(px4::custom_mode::MAIN_MODE_RATTITUDE),        "RATTITUDE" },
	{ px4::define_mode_auto(px4::custom_mode::SUB_MODE_AUTO_MISSION), "AUTO.MISSION" },
	{ px4::define_mode_auto(px4::custom_mode::SUB_MODE_AUTO_LOITER),  "AUTO.LOITER" },
	{ px4::define_mode_auto(px4::custom_mode::SUB_MODE_AUTO_RTL),     "AUTO.RTL" },
	{ px4::define_mode_auto(px4::custom_mode::SUB_MODE_AUTO_LAND),    "AUTO.LAND" },
	{ px4::define_mode_auto(px4::custom_mode::SUB_MODE_AUTO_RTGS),    "AUTO.RTGS" },
	{ px4::define_mode_auto(px4::custom_mode::SUB_MODE_AUTO_READY),   "AUTO.READY" },
	{ px4::define_mode_auto(px4::custom_mode::SUB_MODE_AUTO_TAKEOFF), "AUTO.TAKEOFF" },
	{ px4::define_mode_auto(px4::custom_mode::SUB_MODE_AUTO_FOLLOW_TARGET), "AUTO.FOLLOW_TARGET" },
	{ px4::define_mode_auto(px4::custom_mode::SUB_MODE_AUTO_PRECLAND), "AUTO.PRECLAND" },
}};

示例代码

ros::ServiceClient set_mode_client = nh.serviceClient<mavros_msgs::SetMode>("mavros/set_mode");
mavros_msgs::SetMode offb_set_mode;
offb_set_mode.request.custom_mode = "OFFBOARD";
set_mode_client.call(offb_set_mode);
if(offb_set_mode.response.mode_sent)
    ROS_INFO("Offboard enabled");

注:主要参考网上某位大神的总结,在此表示感谢!

<think>好的,我现在需要分析用户提供的这段ROS代码,并指出其中的问题。首先,我会仔细阅读代码,了解其结构和功能代码开头含了几个ROSMAVROS相关的头文件,比如ros.h、geometry_msgs、mavros_msgs等。然后定义了两个回调函数:yolov5_camera_callback和mavros_pose_callback。在main函数里,初始化了ROS节点,创建了两个订阅者,分别订阅"yolov5_camera"和"/mavros/local_position/pose"这两个话题,然后在循环中调用ros::spinOnce()。 接下来,我需要检查代码中的潜在错误。首先看回调函数。第一个回调yolov5_camera_callback的参数是std_msgs::String,里面使用ROS_INFO输出msg.data.c_str()。这里看起来没问题,因为c_str()返回C风格的字符串,符合ROS_INFO的要求。 然后是mavros_pose_callback,它订阅的是mavros_msgs::State类型消息,但话题名称却是"/mavros/local_position/pose"。这里可能存在不匹配的问题。因为通常来说,/mavros/local_position/pose发布的是geometry_msgs/PoseStamped类型消息,而mavros_msgs/State一般是通过/mavros/state话题发布的。因此,这里回调函数的消息类型和订阅的话题类型不匹配,会导致运行时错误或者无法接收消息。 接下来看订阅者的声明。mission_state_sub订阅的是std_msgs::String类型的"yolov5_camera"话题,回调函数正确。而mavros_state_sub订阅的是mavros_msgs::State类型的/mavros/local_position/pose话题,这里消息类型错误,应该改为geometry_msgs::PoseStamped。 此外,在main函数的while循环中,只调用了ros::spinOnce(),没有其他逻辑。这可能没问题,但如果处理频率不够,spinOnce可能无法及时处理回调。不过通常spinOnce在循环中配合一定的休眠时间使用,比如ros::Rate来控制循环频率。当前代码没有使用Rate,可能导致CPU占用过高。 总结问题点: 1. mavros_state_sub订阅的话题类型不匹配,应该将消息类型改为geometry_msgs::PoseStamped,或者更改订阅的话题名为/mavros/state。 2. 如果确实需要获取位置信息,则需要修正消息类型;如果目的是获取状态信息,则需要修正话题名。 3. 循环中没有使用ros::Rate,可能导致CPU过载。 另外,回调函数中的ROS_INFO在mavros_pose_callback中格式化字符串使用了%d,但msg.mode是字符串类型,这会导致编译错误或者运行时错误,因为%d期望的是整数,而实际传递的是字符串。 所以,这里还存在一个格式化字符串的问题,应该使用%s来输出字符串,例如ROS_INFO("Current mode: %s", msg.mode.c_str()); 但前提是msg.mode确实是字符串类型,比如在mavros_msgs::State中,mode成员是std::string类型,因此正确的输出方式应该是用%s和c_str()。 所以,总结错误: 1. 订阅的话题消息类型不匹配。 2. 回调函数中ROS_INFO的错误格式说明符。 3. 缺少ros::Rate导致的高CPU使用。 可能的修正步骤包括: - 将订阅/mavros/local_position/pose的话题消息类型改为geometry_msgs::PoseStamped,并调整回调函数参数。 - 或者,如果确实需要订阅mavros状态,则更改话题名为/mavros/state。 - 修正ROS_INFO中的格式字符串,使用%s和c_str()。 - 添加ros::Rate来限制循环频率。 最后,检查头文件是否齐全。例如,代码中使用了mavros_msgs/State,所以需要含对应的头文件mavros_msgs/State.h,而代码中已经含,这部分没问题。但geometry_msgs/PoseStamped的头文件也被含,但未被使用,可能因为原计划有相关代码但未实现。 综上,用户提供的代码存在多个问题,需要逐一修正才能正确运行。</think>以下是您提供的ROS代码分析及修正建议,采用分步说明: $\textcolor{green}{\textbf{主要问题分析}}$ 1. $\textbf{话题消息类型不匹配}$ ```cpp // 错误代码片段 ros::Subscriber mavros_state_sub = nh.subscribe<mavros_msgs::State>( "/mavros/local_position/pose", 10, mavros_pose_callback); // 类型错误 ``` - $\textcolor{red}{/mavros/local\_position/pose}$ 实际发布的是 $geometry\_msgs::PoseStamped$ 类型 - $mavros\_msgs::State$ 类型对应话题应为 $\textcolor{blue}{/mavros/state}$ 2. $\textbf{格式化字符串错误}$ ```cpp // 错误回调函数 void mavros_pose_callback(mavros_msgs::State msg) { ROS_INFO("Current state: %d", msg.mode); // mode是字符串类型 } ``` - $mavros\_msgs::State.mode$ 是 $std::string$ 类型 - 使用 $%d$ 格式说明符会导致未定义行为 3. $\textbf{CPU资源消耗}$ ```cpp while (ros::ok()) { ros::spinOnce(); // 无休眠机制 } ``` - 缺少 $ros::Rate$ 控制循环频率 - 可能造成 $\textcolor{orange}{100\%\ CPU\ 占用率}$ $\textcolor{green}{\textbf{修正方案}}$ $\textbf{步骤1:修正话题订阅关系}$ (二选一) $\textcolor{blue}{方案A}$ 订阅位置信息 ```cpp // 修改头文件含 #include <geometry_msgs/PoseStamped.h> // 修改回调函数 void mavros_pose_callback(const geometry_msgs::PoseStamped::ConstPtr& msg) { ROS_INFO("Position: x=%.2f, y=%.2f, z=%.2f", msg->pose.position.x, msg->pose.position.y, msg->pose.position.z); } // 修改订阅器 ros::Subscriber mavros_pose_sub = nh.subscribe<geometry_msgs::PoseStamped>( "/mavros/local_position/pose", 10, mavros_pose_callback); ``` $\textcolor{blue}{方案B}$ 订阅飞控状态 ```cpp // 修改话题名称 ros::Subscriber mavros_state_sub = nh.subscribe<mavros_msgs::State>( "/mavros/state", 10, mavros_pose_callback); // 注意修改回调函数名 // 修改回调函数 void mavros_state_callback(const mavros_msgs::State::ConstPtr& msg) { ROS_INFO("Current mode: %s", msg->mode.c_str()); } ``` $\textbf{步骤2:修正格式化输出}$ ```cpp // 正确格式输出(适用于方案B) ROS_INFO("Connected: %s", msg->connected ? "true" : "false"); ROS_INFO("Armed: %s", msg->armed ? "true" : "false"); ROS_INFO("Mode: %s", msg->mode.c_str()); ``` $\textbf{步骤3:添加循环频率控制}$ ```cpp // 在main循环中添加 ros::Rate rate(10); // 10Hz频率 while (ros::ok()) { ros::spinOnce(); rate.sleep(); // 自动计算休眠时间 } ``` $\textcolor{green}{\textbf{改进后完整代码}}$ ```cpp #include <ros/ros.h> #include <mavros_msgs/State.h> #include <geometry_msgs/PoseStamped.h> #include <std_msgs/String.h> // 回调函数声明 void yolov5_callback(const std_msgs::String::ConstPtr& msg); void pose_callback(const geometry_msgs::PoseStamped::ConstPtr& msg); int main(int argc, char **argv) { ros::init(argc, argv, "enhanced_node"); ros::NodeHandle nh; // 创建订阅器 ros::Subscriber yolov5_sub = nh.subscribe("yolov5_camera", 10, yolov5_callback); ros::Subscriber pose_sub = nh.subscribe("/mavros/local_position/pose", 10, pose_callback); // 控制循环频率 ros::Rate rate(10); while(ros::ok()) { ros::spinOnce(); rate.sleep(); } return 0; } // 回调函数实现 void yolov5_callback(const std_msgs::String::ConstPtr& msg) { ROS_INFO("[YOLOv5] Detection: %s", msg->data.c_str()); } void pose_callback(const geometry_msgs::PoseStamped::ConstPtr& msg) { ROS_INFO_THROTTLE(1.0, // 节流输出,每秒1次 "Position: x=%.2f, y=%.2f, z=%.2f", msg->pose.position.x, msg->pose.position.y, msg->pose.position.z); } ``` $\textcolor{green}{\textbf{改进亮点}}$ 1. 使用 $ROS\_INFO\_THROTTLE$ 控制高频话题的输出频率 2. 添加 $const\ Ptr\&$ 语法提升回调效率 3. 明确的节点命名 ($enhanced\_node$) 4. 规范的代码缩进和注释风格 建议通过 $rostopic\ list$ 和 $rostopic\ type$ 命令验证实际话题类型,确保订阅关系正确。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值