Tutorial?
The aim of this tutorial is to explain how to integrate SIGVerse with ROS operating system.
First, we will show how to install ROS on your operating system, then we will explain step by step how to run SIGVerse controller in ROS node and how to communicate with another node.
The ROS part tutorial is based on the official ROS wiki, you can check it for more details.
To install ROS on your server please refer to the official web site.
In our project we are using catkin, here are the steps to follow to create a ROS workspace:
Run the following command:
$ source /opt/ros/groovy/setup.sh
To create a catkin workspace:
$ mkdir -p ~/catkin_ws/src $ cd ~/catkin_ws/src $ catkin_init_workspace
You can build even though no project is created yet, you just need MakeLists.txt:
$ cd ~/catkin_ws/ $ catkin_make
Run the setup.bash
$ source devel/setup.bash
In order to integrate SIGVerse and ROS, we first need to create ROS package containing two nodes, SIGVerse controller node and ROS command node. The first node, SIGVerse controller node, will receive data from the SIGViewer as messages, then publish them on the message topic, in the other part, ROS command node reads these data and subscribe the corresponding velocity on the velocity topic, the velocity command will be retrieved by the SIGVerse controller node to be used for controlling the robot.
We need to create a new package in the catkin_ws directory containing two nodes.
$ cd ~/catkin_ws/src $ catkin_create_pkg sig_ros
$ cd ~/catkin_ws/sig_ros/src/ $ vim sig_controller.cpp $ vim ros_controller.cpp
sig_controller.cpp
The following is the callback function which preforms the command on the velocity of the robot’s wheels:
void SendController::poseCallback(const Sigvers_Ros::VelocityConstPtr& vel) { Wheel_one = vel->linear; Wheel_two = vel->angular; printf("Velocity 1!!! %f\n", Wheel_one); printf("Velocity 2!!! %f\n", Wheel_two); }
void SendController::onInit(InitEvent &evt) { Wheel_one = 0.0; Wheel_two = 0.0; int argc =0; char** argv = NULL; my = this->getRobotObj(this->myname()); my->setWheel(10.0, 10.0); ros::init(argc, argv, "sig_controller_node"); //Initialize ROS. This allows ROS to do name remapping through the command line -- not important for now. This is also where we specify the name of our node. Node names must be unique in a running system. ros::NodeHandle n; // Create a handle to this process' node. The first NodeHandle created will actually do the initialization of the node, and the last one destructed will cleanup any resources the node was using. velocity = 1; chatter_pub = n.advertise<std_msgs::String>("command_message", 1); pose_sub = n.subscribe<Sigvers_Ros::Velocity>("velocity_command", 1,&SendController::poseCallback,this); ros::Rate loop_rate(10); //A ros::Rate object allows you to specify a frequency that you would like to loop at. It will keep track of how long it has been since the last call to Rate::sleep(), and sleep for the correct amount of time.In this case we tell it we want to run at 10hz. // Running the ros_command node system ("source ~/catkin_ws/devel/setup.sh"); system ("rosrun sig_ros ros_controller &"); }
double SendController::onAction(ActionEvent &evt) { my->setWheelVelocity(Weel_one,Weel_two); ros::spinOnce(); // return 1.0; }
This function allows to control the robot using the appropriate velocity.
This is the node that controls the robot’s velocity:
ros_controller.cpp:
CommandSig::CommandSig(): linear_(0), angular_(0), l_scale_(2.0), a_scale_(2.0) { nh_.param("scale_angular", a_scale_, a_scale_); nh_.param("scale_linear", l_scale_, l_scale_); vel_pub_ = nh_.advertise<Sigvers_Ros::Velocity>("velocity_command", 1); mess_sub = nh_.subscribe("command_message",100,&CommandSig::chatterCallback,this); }
int main(int argc, char** argv) { ros::init(argc, argv, "ros_command_node"); CommandSig Command_sig; ros::Rate loop_rate(10); ros::spin(); return(0); }
void CommandSig::chatterCallback (const std_msgs::String::ConstPtr& msg) { Sigvers_Ros::Velocity vel; if(strcmp("go",msg->data.c_str())==0) { vel.angular = 3.0; vel.linear = 3.0; vel_pub_.publish(vel); } else if(strcmp("back",msg->data.c_str())==0) { vel.angular = -3.0; vel.linear = -3.0; vel_pub_.publish(vel); } else if(strcmp("left" ,msg->data.c_str())==0) { vel.angular = 0.78; vel.linear = -0.78; vel_pub_.publish(vel); sleep(1.8); vel.angular = 0.0; vel.linear = 0.0; vel_pub_.publish(vel); } else if(strcmp("right" ,msg->data.c_str())==0) { vel.angular = -0.78; vel.linear = 0.78; vel_pub_.publish(vel); sleep(1.8); vel.angular = 0.0; vel.linear = 0.0; vel_pub_.publish(vel); } else if(strcmp("stop",msg->data.c_str())==0) { vel.angular = 0.0; vel.linear = 0.0; vel_pub_.publish(vel); } ……… }
You need to have Cmake installed on your server.
Let's edit the CMakeLists.txt file to compile the project:
Cmake parameters:
cmake_minimum_required(VERSION 2.8.3) project(Sigvers_Ros) find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation ) ## Generate messages in the 'msg' folder add_message_files( FILES Velocity.msg ) ## Generate added messages and services with any dependencies listed here generate_messages( DEPENDENCIES std_msgs ) ## include libraries include_directories(include ${catkin_INCLUDE_DIRS}) include_directories(/home/ericgt/sigverse-2.2.0/include/sigverse/home/ericgt/sigverse-2.2.0/include/sigverse/comm/controller)
add_executable(ros_controller src/ros_controller.cpp) target_link_libraries(ros_controller ${catkin_LIBRARIES}) add_dependencies(ros_controller sig_ros_gencpp)
ADD_LIBRARY(sig_ros/sig_controller src/sig_controller.cpp) target_link_libraries(sig_ros/sig_controller ${catkin_LIBRARIES}) add_dependencies(sig_ros/sig_controller sig_ros_gencpp)
$ cd ~/catkin_ws $ catkin_make
A new library will be generated in ~/catkin_ws/devel/libsig_ros.
Run the following command to add this package to ROS packages:
$source ~/catkin_ws2/devel/setup.sh
& Roscd sig_ros
We must have the following output:
$ CMakeLists.txt include msg package.xml src
This shows that the sig_ros package exists.
RobotInMove.xml:
<?xml version="1.0" encoding="utf-8"?> <world name="myworld1"> <gravity x="0.0" y="-980.7" z="0.0"/> <instanciate class="WheelRobot-nii-v1.xml" type="Robot"> <set-attr-value name="name" value="robot_000"/> <set-attr-value name="language" value="c++"/> <set-attr-value name="implementation" value="./libSig_app.so"/> <set-attr-value name="dynamics" value="false"/> <set-attr-value name="x" value="-100.0"/> <set-attr-value name="y" value="30.0"/> <set-attr-value name="z" value="-130.0"/> <set-attr-value name="collision" value="true"/> <!--stereo camera right--> <camera id="1" link="REYE_LINK" direction="0.0 -1.0 1.0" position="0.0 0.0 3.0"/> <!--stereo camera left--> <camera id="2" link="LEYE_LINK" direction="0.0 -1.0 1.0" position="0.0 0.0 3.0"/> <!--distance sensor--> <camera id="3" link="WAIST_LINK0" direction="0.0 1.0 0.0" position="0.0 -5.0 20.0"/> <!--monitoring camera--> <camera id="4" link="WAIST_LINK2" direction="0 0 1" quaternion="0.0 0.0 -0.966 0.259" position="0.0 40.0 120.0"/> </instanciate> </world>
To download the project from GIT repository, use the following link:
git@socio4.iir.nii.ac.jp:~/SigverseGitServer/unstable/usersContribution/tafifet/ROS_SIG_Integration.git
To run the server please follow the these steps:
Go to catkin_ws and and follow these steps :
$ roscore
$ cd ~/catkin_ws/devel/lib/libsig_app $ sigserver.sh -w ./move_robot.xml