0

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]
Bob9710
  • 205
  • 3
  • 15

1 Answers1

0

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;
BTables
  • 4,413
  • 2
  • 11
  • 30
  • sorry one question. x_accel, y_accel, z_accel are defined in the .srv file with float64 x_accel, float64 y_accel, float64 z_accel. Same for x,y,z,w orientation and x,y,z angular velocity? Correct? – Bob9710 Sep 09 '21 at 07:44
  • I add the ROS IMU topic in the question. So taking into account that what would be the .msg and .srv files? – Bob9710 Sep 09 '21 at 08:24
  • Orientation and angular velocity should also be a gloat64 in your srv file. For the above example that’s the only custom msg/srv file needed. You don’t need a custom message just to get imu data via a srv call. – BTables Sep 09 '21 at 11:38
  • so my srv file is float64 x_orient float64 y_orient float64 z_orient float64 w_orient float64 x_veloc float64 y_veloc float64 z_veloc float64 x_accel float64 y_accel float64 z_accel --- bool success – Bob9710 Sep 09 '21 at 11:39
  • I add my service cpp file in the question. Is that right now? – Bob9710 Sep 09 '21 at 11:41
  • That looks like it should be correct to me. – BTables Sep 09 '21 at 12:19
  • so in this way I can just pass the IMU data from the server to the client, right? – Bob9710 Sep 09 '21 at 12:42
  • Yes, you can pass the desired fields via a service call to the client this way. – BTables Sep 09 '21 at 12:44
  • ok. Sorry last thing , can I pass also the orientation_covariance, angular_velocity_covariance and the linear_acceleration_covariance? – Bob9710 Sep 09 '21 at 12:48
  • Sure. ROS service files use msg types as fields. This means you can also add `float64[9] somethings_covariance` to your srv file for covariance just fine. – BTables Sep 09 '21 at 12:56
  • hi. I got error ros_services::ImuValue::Response {aka struct ros_services::ImuValueResponse_ >}’ has no member named ‘x_orient’ – Bob9710 Sep 12 '21 at 11:30
  • That error is going to be because `x_orient` isn't actually a field that was added to your `srv` file – BTables Sep 12 '21 at 16:06
  • yes yes. fix it. Sorry the last question. Can I have more services in one package? Like IMU service file IMU.srv then Sonar.srv then Camera.srv in srv folder and corresponr server and client nodes in srs folder? Or I need separate srv folder for each services? – Bob9710 Sep 13 '21 at 07:46
  • so in CMakeLists.txt file I add this line add_service_files( FILES ImuValue.srv SonarValue.srv ) but still got error fatal error: ros_services/SonarValue.h: No such file or directory #include "ros_services/SonarValue.h" ^~~~~~~~~~~~~~~~~~~~~~~~~~~ Any help? – Bob9710 Sep 13 '21 at 08:03
  • Yes, you can have more than one in each package. Make sure you're running `catkin_make clean` as sometimes stale builds make it into `devel` – BTables Sep 13 '21 at 12:41
  • ok. When run the rosrun ros_services ImuClient Got orient x: 0 Got orient y: 0 Got orient z: 0 Got orient w: 0 – Bob9710 Sep 13 '21 at 13:46
  • all Imu values are 0. How come? – Bob9710 Sep 13 '21 at 13:46
  • I update the latest code in the question. But still the Client responce values are all zero – Bob9710 Sep 13 '21 at 13:54
  • Can't say without seeing all of the code. I'd assume the code isn't caching imu values to put into the response object correctly. This is fairly off topic from the original question so further comments should probably be their own question. – BTables Sep 13 '21 at 14:04
  • so I should open a new question and add the server and client code? – Bob9710 Sep 13 '21 at 14:09
  • I think so. SO best practices is to not have extended discussion in comments; especially if off topic from the original question. – BTables Sep 13 '21 at 14:11
  • ok. I created a new topic and includes the .srv file, server and client node. Pls check. Thanks – Bob9710 Sep 13 '21 at 14:13