Bob9710
Bob9710

Reputation: 205

ROS IMU services, client and server node templates

I would like to create IMU ROS services. I have a Server(in my case is a microcontroller ESC32) that can obtain IMU reading and should pass to the Client (in my case is Raspberry PI 4B) the IMU data when requested for further processing.So I just need to pass the raw IMU data. I would like to start with some ros services template for the IMU server and client node. This is my .srv file

float64 x_orient_in
float64 y_orient_in
float64 z_orient_in
float64 w_orient_in
float64 x_veloc_in
float64 y_veloc_in
float64 z_veloc_in
float64 x_accel_in
float64 y_accel_in
float64 z_accel_in
---
float64 x_orient_out
float64 y_orient_out
float64 z_orient_out
float64 w_orient_out
float64 x_veloc_out
float64 y_veloc_out
float64 z_veloc_out
float64 x_accel_out
float64 y_accel_out
float64 z_accel_out
bool success

This is my server cpp

#include "ros/ros.h"
#include <sensor_msgs/Imu.h>
#include "ros_services/ImuValue.h"

bool get_val(ros_services::ImuValue::Request  &req, ros_services::ImuValue::Response &res)
{
    
    ROS_INFO("sending back response");
    res.x_orient_out= req.x_orient_in;
    res.y_orient_out= req.y_orient_in;
    res.z_orient_out= req.z_orient_in;
    res.w_orient_out= req.w_orient_in;
    res.x_veloc_out= req.x_veloc_in;
    res.y_veloc_out= req.y_veloc_in;
    res.z_veloc_out= req.z_veloc_in;
    res.x_accel_out= req.x_accel_in;
    res.x_accel_out= req.x_accel_in;
    res.x_accel_out= req.x_accel_in;
    
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "imu_status_server");
  ros::NodeHandle n;
  ros::ServiceServer service = n.advertiseService("imu_status_server", get_val);
  ROS_INFO("Starting server...");
  ros::spin();

  return 0;
}

And my IMU ros topic is this

header: 
  seq: 45672
  stamp: 
    secs: 956
    nsecs: 962000000
  frame_id: "thrbot/imu_link"
orientation: 
  x: 0.0697171053094
  y: 0.00825242210747
  z: 0.920964387685
  w: -0.383270164991
orientation_covariance: [0.0001, 0.0, 0.0, 0.0, 0.0001, 0.0, 0.0, 0.0, 0.0001]
angular_velocity: 
  x: 0.00156996015527
  y: 0.0263644782572
  z: -0.0617661883137
angular_velocity_covariance: [1.1519236000000001e-07, 0.0, 0.0, 0.0, 1.1519236000000001e-07, 0.0, 0.0, 0.0, 1.1519236000000001e-07]
linear_acceleration: 
  x: 1.32039048367
  y: -0.376341478938
  z: 9.70643773249
linear_acceleration_covariance: [1.6e-05, 0.0, 0.0, 0.0, 1.6e-05, 0.0, 0.0, 0.0, 1.6e-05]

Upvotes: 0

Views: 215

Answers (1)

BTables
BTables

Reputation: 4843

I would heavily suggest checking out the ros wiki tutorials. They have a lot of info that can also save you some time. That being said, you would just set it up like any other service call. You will probably also have to create your own message that might look something like this:

float64 x_accel
float64 y_accel
float64 z_accel
---
bool success

Then you just need a server node to handling incoming requests like this:

#include "ros/ros.h"
#include "your_service/service_file.h"

bool get_val(your_service::service_file::Request  &req,
         your_service::service_file::Response &res)
{
  res.x_accel = get_accel_x(); //Defined somewhere else by you
  res.y_accel = get_accel_y(); //Defined somewhere else by you
  res.z_accel = get_accel_z(); //Defined somewhere else by you
  return true;
}

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

  ros::ServiceServer service = n.advertiseService("imu_status_server", add);
  ROS_INFO("Starting server...");
  ros::spin();

  return 0;
}

Finally, the client can make calls to the server like this

ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("imu_status_server");
your_service::service_file srv;
client.call(srv);
std::cout << "Got accel x: " << srv.response.x_accel << std::endl;

Upvotes: 0

Related Questions