How to call a ROS service with a launch file every time press the joystick to control UUV vehicle in Gazebo simulation?
HI
Im using Gazebo 9 and ROS melodic for some UUV Simulation. I created a ROS Service that pass the IMU sensors values from the Server to Client. Now I would like to use this service as a sensor feedback to the controller every time I control the UUV( means every time I press the joystick). Here are the Server and Client Node and the launch control file.
Server node
#include "ros/ros.h"
#include <sensor_msgs/Imu.h>
#include "imu_service/ImuValue.h"
ros::ServiceServer service;
double current_x_orientation_s;
double get_imu_orientation_x;
bool get_val(imu_service::ImuValue::Request &req, imu_service::ImuValue::Response &res)
{
ROS_INFO("sending back response");
res.current_x_orientation_s = get_imu_orientation_x;
//.. same for the other IMU values
}
void imuCallback(const sensor_msgs::ImuConstPtr& msg)
{
current_x_orientation_s= msg->orientation.x;
get_imu_orientation_x=current_x_orientation_s;
// ..same for other IMU values
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "imu_status_server");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("/thrbot/imu", 10, imuCallback);
service = n.advertiseService("imu_status_server", get_val);
ROS_INFO("Starting server...");
ros::spin();
return 0;
}
Client node
#include "ros/ros.h"
#include "imu_service/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<imu_service::ImuValue>("imu_status_server");
imu_service::ImuValue srv;
client.call(srv);
std::cout << "Got accel x: " << srv.response.current_x_orientation_s << std::endl;
if (client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.current_x_orientation_s);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
return 0;
}
And this is the launch file I like to use to call ROS Service every time I press the joystick to control the UUV robot
<launch> <arg name="namespace" default="thrbot"/> <arg name="joy_id" default="0"/> <arg name="axis_x" default="4"/> <arg name="axis_y" default="3"/> <arg name="axis_z" default="1"/> <arg name="axis_yaw" default="0"/>
<arg name="gui_on" default="true"/>
<include file="$(find thrbot_control)/launch/start_thruster_manager.launch">
<arg name="uuv_name" value="$(arg namespace)"/>
</include>
<group ns="$(arg namespace)">
<rosparam file="$(find thrbot_control)/config/inertial.yaml" command="load"/>
<rosparam file="$(find thrbot_control)/config/vel_pid_control.yaml" command="load"/>
<node pkg="uuv_control_cascaded_pid" type="AccelerationControl.py" name="acceleration_control"
output="screen">
<param name="tf_prefix" type="string" value="$(arg namespace)/" />
</node>
<node pkg="uuv_control_cascaded_pid" type="VelocityControl.py" name="velocity_control"
output="screen">
<remap from="odom" to="pose_gt"/>
</node>
</group>
<include file="$(find uuv_teleop)/launch/uuv_teleop.launch">
<arg name="uuv_name" value="$(arg namespace)"/>
<arg name="joy_id" value="$(arg joy_id)"/>
<arg name="output_topic" value="cmd_vel"/>
<arg name="message_type" value="twist"/>
<arg name="axis_yaw" value="$(arg axis_yaw)"/>
<arg name="axis_x" value="$(arg axis_x)"/>
<arg name="axis_y" value="$(arg axis_y)"/>
<arg name="axis_z" value="$(arg axis_z)"/>
<arg name="gain_yaw" default="0.1"/>
<arg name="gain_x" default="0.2"/>
<arg name="gain_y" default="0.2"/>
<arg name="gain_z" default="0.2"/>
<!--arg name="gain_yaw" default="0.1"/> -->
<!--arg name="gain_x" default="0.2"/> -->
< ...
This approach is going to have very low performance. Services are not designed to be called multiple times a second.
What is your question?
no. Its not meant to be called multiple times a second. It was just example. Can be called every 5 seconds or even every 30 seconds. I just want to be called by press button on the joystick. The frequency of the call is irrelevant. OK?