Revision 40 as of 2009-11-02 18:28:57

Clear message

Note: This tutorial assumes that you have completed the previous tutorials: Running a realtime joint controller.
(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Communicating with a realtime joint controller

Description: This tutorial teaches you how to communicate with a controller over ROS.

Tutorial Level: INTERMEDIATE

Next Tutorial: Adding a PID to a realtime joint controller

srv/SetAmplitude.srv

  float64 amplitude
  ---
  float64 amplitude[

CmakeLists.txt

  rosbuild_gensrv()

include/my_controller_pkg/my_controller.h

Toggle line numbers
   1 #include <pr2_controller_interface/controller.h>
   2 #include <pr2_mechanism_model/joint.h>
   3 #include <ros/ros.h>
   4 #include <my_controller_pkg/SetAmplitude.h>
   5 
   6 namespace controller{
   7 
   8 class MyController: public pr2_controller_interface::Controller
   9 {
  10 private:
  11   bool setAmplitude(my_controller_pkg::SetAmplitude::Request& req,
  12                     my_controller_pkg::SetAmplitude::Response& resp);
  13 
  14   pr2_mechanism_model::JointState* joint_state_;
  15   double init_pos_;
  16   double amplitude_;
  17   ros::ServiceServer srv_;
  18 
  19 public:
  20   bool init(pr2_mechanism_model::RobotState *robot,
  21             const ros::NodeHandle &n);
  22   bool starting();
  23   void update();
  24   void stopping();
  25 };
  26 }

src/my_controller.cpp

Toggle line numbers
   1 #include "my_controller_pkg/my_controller.h"
   2 #include <pluginlib/class_list_macros.h>
   3 
   4 using namespace controller;
   5 
   6 
   7 /// Controller initialization in non-relatime
   8 bool MyController::init(pr2_mechanism_model::RobotState *robot,
   9                         const ros::NodeHandle &n)
  10 {
  11   std::string joint_name;
  12   if (!n.getParam("joint_name", joint_name))
  13   {
  14     ROS_ERROR("No joint given in namespace: %s)",
  15               n.getNamespace().c_str());
  16     return false;
  17   }
  18 
  19   joint_state_ = robot->getJointState(joint_name);
  20   if (!joint_state_)
  21   {
  22     ROS_ERROR("MyController could not find joint named \"%s\"",
  23               joint_name.c_str());
  24     return false;
  25   }
  26 
  27   ros::NodeHandle n2(n);
  28   srv_ = n2.advertiseService("set_amplitude", 
  29                              &MyController::setAmplitude, this);
  30   amplitude_ = 0.5;
  31   return true;
  32 }
  33 
  34 
  35 /// Controller startup in realtime
  36 bool MyController::starting()
  37 {
  38   init_pos_ = joint_state_->position_;
  39   return true;
  40 }
  41 
  42 
  43 /// Controller update loop in realtime
  44 void MyController::update()
  45 {
  46   double desired_pos = init_pos_ + amplitude_ * sin(ros::Time::now().toSec());
  47   double current_pos = joint_state_->position_;
  48   joint_state_->commanded_effort_ = 10 * (desired_pos - current_pos);
  49 }
  50 
  51 
  52 /// Controller stopping in realtime
  53 void MyController::stopping()
  54 {}
  55 
  56 
  57 /// Service call to set amplitude of sin
  58 bool MyController::setAmplitude(my_controller_pkg::SetAmplitude::Request& req,
  59                                 my_controller_pkg::SetAmplitude::Response& resp)
  60 {
  61   if (fabs(req.amplitude) < 2.0){
  62     amplitude_ = req.amplitude;
  63     ROS_INFO("Mycontroller: set amplitude to %f", req.amplitude);
  64   }
  65   else
  66     ROS_WARN("MyController: requested amplitude %f to large", req.amplitude);
  67 
  68   resp.amplitude = amplitude_;
  69   return true;
  70 }
  71 
  72 
  73 /// Register controller to pluginlib
  74 PLUGINLIB_REGISTER_CLASS(MyController,
  75                          controller::MyController,
  76                          pr2_controller_interface::Controller)

  $ rosservice call /my_tutorial_controller/set_amplitude 0.1

  $ rosservice call /my_tutorial_controller/set_amplitude 2.9