void Servo::Load(gazebo::physics::ModelPtr model, sdf::ElementPtr sdf) { this->model = model; signal = 0; // parse SDF Properries joint = model->GetJoint(sdf->Get<std::string>("joint")); if (sdf->HasElement("topic")) { topic = sdf->Get<std::string>("topic"); } else { topic = "~/" + sdf->GetAttribute("name")->GetAsString(); } if (sdf->HasElement("torque")) { torque = sdf->Get<double>("torque"); } else { torque = 5; } gzmsg << "initializing servo: " << topic << " joint=" << joint->GetName() << " torque=" << torque << std::endl; // Connect to Gazebo transport for messaging std::string scoped_name = model->GetWorld()->GetName() + "::" + model->GetScopedName(); boost::replace_all(scoped_name, "::", "/"); node = gazebo::transport::NodePtr(new gazebo::transport::Node()); node->Init(scoped_name); sub = node->Subscribe(topic, &Servo::Callback, this); // connect to the world update event // this will call update every iteration updateConn = gazebo::event::Events::ConnectWorldUpdateBegin( boost::bind(&Servo::Update, this, _1)); }
void DCMotor::Load(gazebo::physics::ModelPtr model, sdf::ElementPtr sdf) { this->model = model; signal = 0; // Parse SDF properties joint = model->GetJoint(sdf->Get<std::string>("joint")); if (sdf->HasElement("topic")) { topic = sdf->Get<std::string>("topic"); } else { topic = "~/" + sdf->GetAttribute("name")->GetAsString(); } if (sdf->HasElement("multiplier")) { multiplier = sdf->Get<double>("multiplier"); } else { multiplier = 1; } gzmsg << "Initializing motor: " << topic << " joint=" << joint->GetName() << " multiplier=" << multiplier << std::endl; // Connect to Gazebo transport for messaging std::string scoped_name = model->GetWorld()->GetName() + "::" + model->GetScopedName(); boost::replace_all(scoped_name, "::", "/"); node = gazebo::transport::NodePtr(new gazebo::transport::Node()); node->Init(scoped_name); sub = node->Subscribe(topic, &DCMotor::Callback, this); // Connect to the world update event. // This will trigger the Update function every Gazebo iteration updateConn = gazebo::event::Events::ConnectWorldUpdateBegin( boost::bind(&DCMotor::Update, this, _1)); }
bool initSim(ros::NodeHandle nh, gazebo::physics::ModelPtr model) { // Get the gazebo joints that correspond to the robot joints for(unsigned int j=0; j < n_dof_; j++) { ROS_INFO_STREAM("Getting pointer to gazebo joint: "<<joint_name_[j]); gazebo::physics::JointPtr joint = model->GetJoint(joint_name_[j]); if (joint) { sim_joints_.push_back(joint); } else { ROS_ERROR_STREAM( "This robot has a joint named \""<<joint_name_[j] <<"\" which is not in the gazebo model."); return false; } } return true; }
JointMotor::JointMotor( ::gazebo::physics::ModelPtr _model, const std::string &_partId, const std::string &_motorId, sdf::ElementPtr _motor, const unsigned int _outputs) : Motor(_model, _partId, _motorId, _outputs) { if (not _motor->HasAttribute("joint")) { std::cerr << "JointMotor requires a `joint` attribute." << std::endl; throw std::runtime_error("Motor error"); } auto jointName = _motor->GetAttribute("joint")->GetAsString(); this->joint_ = _model->GetJoint(jointName); if (not this->joint_) { std::cerr << "Cannot locate joint motor `" << jointName << "`" << std::endl; throw std::runtime_error("Motor error"); } this->jointName_ = this->joint_->GetScopedName(); }
bool DefaultRobotHWSim::initSim( const std::string& robot_namespace, ros::NodeHandle model_nh, gazebo::physics::ModelPtr parent_model, const urdf::Model *const urdf_model, std::vector<transmission_interface::TransmissionInfo> transmissions) { // getJointLimits() searches joint_limit_nh for joint limit parameters. The format of each // parameter's name is "joint_limits/<joint name>". An example is "joint_limits/axle_joint". const ros::NodeHandle joint_limit_nh(model_nh, robot_namespace); // Resize vectors to our DOF n_dof_ = transmissions.size(); joint_names_.resize(n_dof_); joint_types_.resize(n_dof_); joint_lower_limits_.resize(n_dof_); joint_upper_limits_.resize(n_dof_); joint_effort_limits_.resize(n_dof_); joint_control_methods_.resize(n_dof_); pid_controllers_.resize(n_dof_); joint_position_.resize(n_dof_); joint_velocity_.resize(n_dof_); joint_effort_.resize(n_dof_); joint_effort_command_.resize(n_dof_); joint_position_command_.resize(n_dof_); joint_velocity_command_.resize(n_dof_); // Initialize values for(unsigned int j=0; j < n_dof_; j++) { // Check that this transmission has one joint if(transmissions[j].joints_.size() == 0) { ROS_WARN_STREAM_NAMED("default_robot_hw_sim","Transmission " << transmissions[j].name_ << " has no associated joints."); continue; } else if(transmissions[j].joints_.size() > 1) { ROS_WARN_STREAM_NAMED("default_robot_hw_sim","Transmission " << transmissions[j].name_ << " has more than one joint. Currently the default robot hardware simulation " << " interface only supports one."); continue; } std::vector<std::string> joint_interfaces = transmissions[j].joints_[0].hardware_interfaces_; if (joint_interfaces.empty() && !(transmissions[j].actuators_.empty()) && !(transmissions[j].actuators_[0].hardware_interfaces_.empty())) { // TODO: Deprecate HW interface specification in actuators in ROS J joint_interfaces = transmissions[j].actuators_[0].hardware_interfaces_; ROS_WARN_STREAM_NAMED("default_robot_hw_sim", "The <hardware_interface> element of tranmission " << transmissions[j].name_ << " should be nested inside the <joint> element, not <actuator>. " << "The transmission will be properly loaded, but please update " << "your robot model to remain compatible with future versions of the plugin."); } if (joint_interfaces.empty()) { ROS_WARN_STREAM_NAMED("default_robot_hw_sim", "Joint " << transmissions[j].joints_[0].name_ << " of transmission " << transmissions[j].name_ << " does not specify any hardware interface. " << "Not adding it to the robot hardware simulation."); continue; } else if (joint_interfaces.size() > 1) { ROS_WARN_STREAM_NAMED("default_robot_hw_sim", "Joint " << transmissions[j].joints_[0].name_ << " of transmission " << transmissions[j].name_ << " specifies multiple hardware interfaces. " << "Currently the default robot hardware simulation interface only supports one. Using the first entry!"); //continue; } // Add data from transmission joint_names_[j] = transmissions[j].joints_[0].name_; joint_position_[j] = 1.0; joint_velocity_[j] = 0.0; joint_effort_[j] = 1.0; // N/m for continuous joints joint_effort_command_[j] = 0.0; joint_position_command_[j] = 0.0; joint_velocity_command_[j] = 0.0; const std::string& hardware_interface = joint_interfaces.front(); // Debug ROS_DEBUG_STREAM_NAMED("default_robot_hw_sim","Loading joint '" << joint_names_[j] << "' of type '" << hardware_interface << "'"); // Create joint state interface for all joints js_interface_.registerHandle(hardware_interface::JointStateHandle( joint_names_[j], &joint_position_[j], &joint_velocity_[j], &joint_effort_[j])); // Decide what kind of command interface this actuator/joint has hardware_interface::JointHandle joint_handle; if(hardware_interface == "EffortJointInterface") { // Create effort joint interface joint_control_methods_[j] = EFFORT; joint_handle = hardware_interface::JointHandle(js_interface_.getHandle(joint_names_[j]), &joint_effort_command_[j]); ej_interface_.registerHandle(joint_handle); } else if(hardware_interface == "PositionJointInterface") { // Create position joint interface joint_control_methods_[j] = POSITION; joint_handle = hardware_interface::JointHandle(js_interface_.getHandle(joint_names_[j]), &joint_position_command_[j]); pj_interface_.registerHandle(joint_handle); } else if(hardware_interface == "VelocityJointInterface") { // Create velocity joint interface joint_control_methods_[j] = VELOCITY; joint_handle = hardware_interface::JointHandle(js_interface_.getHandle(joint_names_[j]), &joint_velocity_command_[j]); vj_interface_.registerHandle(joint_handle); } else { ROS_FATAL_STREAM_NAMED("default_robot_hw_sim","No matching hardware interface found for '" << hardware_interface ); return false; } // Get the gazebo joint that corresponds to the robot joint. //ROS_DEBUG_STREAM_NAMED("default_robot_hw_sim", "Getting pointer to gazebo joint: " // << joint_names_[j]); gazebo::physics::JointPtr joint = parent_model->GetJoint(joint_names_[j]); if (!joint) { ROS_ERROR_STREAM("This robot has a joint named \"" << joint_names_[j] << "\" which is not in the gazebo model."); return false; } sim_joints_.push_back(joint); registerJointLimits(joint_names_[j], joint_handle, joint_control_methods_[j], joint_limit_nh, urdf_model, &joint_types_[j], &joint_lower_limits_[j], &joint_upper_limits_[j], &joint_effort_limits_[j]); if (joint_control_methods_[j] != EFFORT) { // Initialize the PID controller. If no PID gain values are found, use joint->SetAngle() or // joint->SetVelocity() to control the joint. const ros::NodeHandle nh(model_nh, robot_namespace + "/gazebo_ros_control/pid_gains/" + joint_names_[j]); if (pid_controllers_[j].init(nh, true)) { switch (joint_control_methods_[j]) { case POSITION: joint_control_methods_[j] = POSITION_PID; break; case VELOCITY: joint_control_methods_[j] = VELOCITY_PID; break; } } else { // joint->SetMaxForce() must be called if joint->SetAngle() or joint->SetVelocity() are // going to be called. joint->SetMaxForce() must *not* be called if joint->SetForce() is // going to be called. //joint->SetMaxForce(0, joint_effort_limits_[j]); joint->SetParam("max_force", 0, joint_effort_limits_[j]); } } } // Register interfaces registerInterface(&js_interface_); registerInterface(&ej_interface_); registerInterface(&pj_interface_); registerInterface(&vj_interface_); // Initialize the emergency stop code. e_stop_active_ = false; last_e_stop_active_ = false; return true; }