control_node.cpp
Go to the documentation of this file.
00001 #include <socketcan_interface/dispatcher.h>
00002 #include <socketcan_interface/socketcan.h>
00003 #include <canopen_chain_node/ros_chain.h>
00004 
00005 #include <canopen_motor_node/robot_layer.h>
00006 
00007 using namespace can;
00008 using namespace canopen;
00009 
00010 
00011 
00012 class XmlRpcSettings : public Settings{
00013 public:
00014     XmlRpcSettings() {}
00015     XmlRpcSettings(const XmlRpc::XmlRpcValue &v) : value_(v) {}
00016     XmlRpcSettings& operator=(const XmlRpc::XmlRpcValue &v) { value_ = v; return *this; }
00017 private:
00018     virtual bool getRepr(const std::string &n, std::string & repr) const {
00019         if(value_.hasMember(n)){
00020             std::stringstream sstr;
00021             sstr << const_cast< XmlRpc::XmlRpcValue &>(value_)[n]; // does not write since already existing
00022             repr = sstr.str();
00023             return true;
00024         }
00025         return false;
00026     }
00027     XmlRpc::XmlRpcValue value_;
00028 
00029 };
00030 
00031 class MotorChain : public RosChain{
00032     ClassAllocator<canopen::MotorBase> motor_allocator_;
00033     boost::shared_ptr< LayerGroupNoDiag<MotorBase> > motors_;
00034     boost::shared_ptr<RobotLayer> robot_layer_;
00035 
00036     boost::shared_ptr< ControllerManagerLayer> cm_;
00037 
00038     virtual bool nodeAdded(XmlRpc::XmlRpcValue &params, const boost::shared_ptr<canopen::Node> &node, const boost::shared_ptr<Logger> &logger)
00039     {
00040         std::string name = params["name"];
00041         std::string &joint = name;
00042         if(params.hasMember("joint")) joint.assign(params["joint"]);
00043 
00044         if(!robot_layer_->getJoint(joint)){
00045             ROS_ERROR_STREAM("joint " + joint + " was not found in URDF");
00046             return false;
00047         }
00048 
00049         std::string alloc_name = "canopen::Motor402::Allocator";
00050         if(params.hasMember("motor_allocator")) alloc_name.assign(params["motor_allocator"]);
00051 
00052         XmlRpcSettings settings;
00053         if(params.hasMember("motor_layer")) settings = params["motor_layer"];
00054 
00055         boost::shared_ptr<MotorBase> motor;
00056 
00057         try{
00058             motor = motor_allocator_.allocateInstance(alloc_name, name + "_motor", node->getStorage(), settings);
00059         }
00060         catch( const std::exception &e){
00061             std::string info = boost::diagnostic_information(e);
00062             ROS_ERROR_STREAM(info);
00063             return false;
00064         }
00065 
00066         if(!motor){
00067             ROS_ERROR_STREAM("Could not allocate motor.");
00068             return false;
00069         }
00070 
00071         motor->registerDefaultModes(node->getStorage());
00072         motors_->add(motor);
00073         logger->add(motor);
00074 
00075         boost::shared_ptr<HandleLayer> handle( new HandleLayer(joint, motor, node->getStorage(), params));
00076 
00077         canopen::LayerStatus s;
00078         if(!handle->prepareFilters(s)){
00079             ROS_ERROR_STREAM(s.reason());
00080             return false;
00081         }
00082 
00083         robot_layer_->add(joint, handle);
00084         logger->add(handle);
00085 
00086         return true;
00087     }
00088 
00089 public:
00090     MotorChain(const ros::NodeHandle &nh, const ros::NodeHandle &nh_priv): RosChain(nh, nh_priv), motor_allocator_("canopen_402", "canopen::MotorBase::Allocator"){}
00091 
00092     virtual bool setup_chain() {
00093         motors_.reset( new LayerGroupNoDiag<MotorBase>("402 Layer"));
00094         robot_layer_.reset( new RobotLayer(nh_));
00095 
00096         ros::Duration dur(0.0) ;
00097 
00098         if(RosChain::setup_chain()){
00099             add(motors_);
00100             add(robot_layer_);
00101 
00102             if(!nh_.param("use_realtime_period", false)){
00103                 dur.fromSec(boost::chrono::duration<double>(update_duration_).count());
00104                 ROS_INFO_STREAM("Using fixed control period: " << dur);
00105             }else{
00106                 ROS_INFO("Using real-time control period");
00107             }
00108             cm_.reset(new ControllerManagerLayer(robot_layer_, nh_, dur));
00109             add(cm_);
00110 
00111             return true;
00112         }
00113 
00114         return false;
00115     }
00116 };
00117 
00118 int main(int argc, char** argv){
00119   ros::init(argc, argv, "canopen_motor_chain_node");
00120   ros::AsyncSpinner spinner(0);
00121   spinner.start();
00122 
00123   ros::NodeHandle nh;
00124   ros::NodeHandle nh_priv("~");
00125 
00126   MotorChain chain(nh, nh_priv);
00127 
00128   if(!chain.setup()){
00129       return 1;
00130   }
00131 
00132   ros::waitForShutdown();
00133   return 0;
00134 }


canopen_motor_node
Author(s): Mathias Lüdtke
autogenerated on Thu Jun 6 2019 20:44:07