-
Notifications
You must be signed in to change notification settings - Fork 2
Accessing the ronex data directly from a controller
This tutorial shows how you can access RoNex data directly from a controller.
As input, we use here a potentiometer (a three-terminal resistor with a sliding contact that forms an adjustable voltage divider). And it is connected to the first analogue sampling channel (i.e., index 0) on the General I/O module with alias "test_ronex".
Files belonging to this tutorial can be found in the sr_ronex_examples package.
- model/simple_robot.urdf: a description of the robot.
- launch/sr_ronex_simple_controller.launch: a launch file to start the drivers, the controllers, and a few utils.
- config/data_access_controller.yaml: the parameter settings.
- controller_plugins.xml: the plugin settings.
For a detailed desription of how these files are use, please read this tutorial: Control a Joint Based Robot with RoNeX.
Change directories to your sr_ronex_examples package.
$ roscd sr_ronex_examples/
$ cd src
$ pwd
C++ header file sr_ronex_simple_controller.hpp is located inside the include/sr_ronex_examples directory.
/*
* Copyright (c) 2013, Shadow Robot Company, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
/**
* @file sr_ronex_simple_controller.hpp
* @author Yi Li <[email protected]>
* @brief Access RoNeX data directly from the controller.
**/
#ifndef _SR_RONEX_SIMPLE_CONTROLLER_HPP_
#define _SR_RONEX_SIMPLE_CONTROLLER_HPP_
#include <ros/node_handle.h>
#include <pr2_controller_interface/controller.h>
#include <sr_ronex_hardware_interface/mk2_gio_hardware_interface.hpp>
#include <realtime_tools/realtime_publisher.h>
#include <sr_ronex_utilities/sr_ronex_utilities.hpp>
#include <std_msgs/Bool.h>
#include <sr_ronex_msgs/PWM.h>
namespace ronex
{
class SrRoNeXSimpleController
: public pr2_controller_interface::Controller
{
public:
SrRoNeXSimpleController();
virtual ~SrRoNeXSimpleController();
virtual bool init(pr2_mechanism_model::RobotState* robot, ros::NodeHandle &n);
virtual void starting();
virtual void update();
virtual void stopping();
private:
int loop_count_;
ronex::GeneralIO* general_io_;
};
}
#endif /* _SR_RONEX_SIMPLE_CONTROLLER_HPP_ */
C++ source file sr_ronex_simple_controller.cpp is located inside the src directory.
/*
* Copyright (c) 2013, Shadow Robot Company, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
/**
* @file sr_ronex_simple_controller.cpp
* @author Yi Li <[email protected]>
* @brief Access RoNeX data directly from the controller.
**/
#include "sr_ronex_examples/sr_ronex_simple_controller.hpp"
#include "pluginlib/class_list_macros.h"
PLUGINLIB_EXPORT_CLASS( ronex::SrRoNeXSimpleController, pr2_controller_interface::Controller)
namespace ronex
{
SrRoNeXSimpleController::SrRoNeXSimpleController()
: loop_count_(0)
{
}
SrRoNeXSimpleController::~SrRoNeXSimpleController()
{
}
bool SrRoNeXSimpleController::init(pr2_mechanism_model::RobotState* robot, ros::NodeHandle &n)
{
assert (robot);
std::string path("/ronex/general_io/test_ronex");
general_io_ = static_cast<ronex::GeneralIO*>( robot->model_->hw_->getCustomHW(path) );
if( general_io_ == NULL)
{
ROS_ERROR_STREAM("Could not find RoNeX module (i.e., test_ronex). The controller is not loaded.");
return false;
}
return true;
}
void SrRoNeXSimpleController::starting()
{
// Do nothing.
}
void SrRoNeXSimpleController::update()
{
double position = general_io_->state_.analogue_[0];
if (loop_count_++ % 100 == 0)
{
ROS_INFO_STREAM( "Position = " << position );
loop_count_ = 0;
}
}
void SrRoNeXSimpleController::stopping()
{
// Do nothing.
}
}
First we look for General I/O module "test_ronex".
bool SrRoNeXSimpleController::init(pr2_mechanism_model::RobotState* robot, ros::NodeHandle &n)
{
assert (robot);
std::string path("/ronex/general_io/test_ronex");
general_io_ = static_cast<ronex::GeneralIO*>( robot->model_->hw_->getCustomHW(path) );
if( general_io_ == NULL)
{
ROS_ERROR_STREAM("Could not find RoNeX module (i.e., test_ronex). The controller is not loaded.");
return false;
}
return true;
}
If the module is found, we repeatedly read the data from the first analogue sampling channel and output it to the console.
void SrRoNeXSimpleController::update()
{
double position = general_io_->state_.analogue_[0];
if (loop_count_++ % 100 == 0)
{
ROS_INFO_STREAM( "Position = " << position );
loop_count_ = 0;
}
}