You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用launch文件启动ROS服务返回IMU值为0问题求助

问题根因
  • 启动时序不匹配:launch启动时两个节点同时运行,服务端节点刚启动还没收到/thrbot/imu话题的第一帧数据,存储IMU数值的全局变量还保持初始化的0值,此时客户端已经完成服务调用,自然返回0。手动执行rosrun时一般会先启动服务端等待数据接收完成后再启动客户端,所以数值正常。
  • 服务端回调逻辑缺陷:你编写的服务处理函数get_val声明了bool返回类型,但没有显式返回值,属于未定义行为,会导致服务调用状态异常。
  • 客户端无等待逻辑:客户端启动后直接调用服务,既没有等待服务端完成注册,也没有等待IMU数据完成首次接收。
解决方案

你可以任选以下一种方案快速修复,也可以组合使用提升稳定性:

方案1:修改客户端添加等待逻辑(推荐)

修改客户端代码,增加服务等待和数据延迟逻辑,示例如下:

#include "ros/ros.h"
#include "ros_services/ImuValue.h"
#include <cstdlib>

int main(int argc, char **argv)
{
    ros::init(argc,argv,"imu_client_node");
    ros::NodeHandle n;
    ros::ServiceClient client = n.serviceClient<ros_services::ImuValue>("imu_status_server");
    // 等待服务注册完成,最长等待5秒
    if(!ros::service::waitForService("imu_status_server", ros::Duration(5.0))){
        ROS_ERROR("等待IMU服务超时");
        return 1;
    }
    ros_services::ImuValue srv;
    // 等待1秒保证服务端拿到第一帧IMU数据
    ros::Duration(1.0).sleep();
    if(client.call(srv)){
        std::cout << "Got accel x: " << srv.response.current_x_orientation_s << std::endl;
    }else{
        ROS_ERROR("调用IMU服务失败");
        return 1;
    }
    return 0;
}

方案2:修改launch文件添加启动延迟(无需改代码)

直接给客户端节点加启动延迟,让服务端先运行2秒再启动客户端,修改后的launch文件如下:

<?xml version="1.0"?>
<launch>
    <node name="ImuServerService" pkg="ros_services" type="ImuServerService" output="screen">
    </node>
    <node name="ImuClientService" pkg="ros_services" type="ImuClientService" output="screen" launch-prefix="sleep 2 && "/>
</launch>

方案3:优化服务端逻辑(提升健壮性)

给服务端增加数据接收标记,未收到IMU数据时直接返回服务调用失败,引导客户端重试,修改点如下:

// 新增全局标记位
bool imu_received = false;

bool get_val(imu_service::ImuValue::Request  &req, imu_service::ImuValue::Response &res)
{
    if(!imu_received){
        ROS_WARN("IMU数据未就绪,服务调用失败");
        return false;
    }
    ROS_INFO("sending back response");    
    res.current_x_orientation_s = get_imu_orientation_x;
    // 必须显式返回true表示服务处理成功
    return true;
}

void imuCallback(const  sensor_msgs::ImuConstPtr& msg)
{
     current_x_orientation_s= msg->orientation.x;
     get_imu_orientation_x=current_x_orientation_s;
     // 标记数据已接收
     imu_received = true;
}

内容的提问来源于stack exchange,提问作者Bob9710

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 23:06:03