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];
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 ¶ms, 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 }