17 #include <ignition/gazebo/components/JointForce.hh>
18 #include <ignition/gazebo/components/JointForceCmd.hh>
19 #include <ignition/gazebo/components/JointPosition.hh>
20 #include <ignition/gazebo/components/JointVelocity.hh>
21 #include <ignition/gazebo/components/JointVelocityCmd.hh>
22 #include <ignition/gazebo/components/Name.hh>
23 #include <ignition/gazebo/components/ParentEntity.hh>
24 #include <ignition/transport/Node.hh>
82 ignition::gazebo::EntityComponentManager*
ecm_;
88 ignition::transport::Node
node;
103 std::map<std::string, ignition::gazebo::Entity> & enableJoints,
104 ignition::gazebo::EntityComponentManager & ecm,
105 std::vector<transmission_interface::TransmissionInfo> transmissions,
108 this->
dataPtr = std::make_unique<IgnitionSystemPrivate>();
111 this->
nh_ = model_nh;
113 this->
dataPtr->n_dof_ = transmissions.size();
114 this->
dataPtr->update_rate_ = update_rate;
120 if (this->
dataPtr->n_dof_ == 0) {
121 ROS_WARN_STREAM(
"[Ignition ROS Control] There is not joint available");
125 std::string joint_name;
126 for (
unsigned int j = 0; j < this->
dataPtr->n_dof_; j++) {
127 joint_name = this->
dataPtr->joints_[j].name = transmissions[j].joints_[0].name_;
129 ignition::gazebo::Entity simjoint = enableJoints[joint_name];
130 this->
dataPtr->joints_[j].sim_joint = simjoint;
133 if (!ecm.EntityHasComponentType(
135 ignition::gazebo::components::JointPosition().TypeId()))
137 ecm.CreateComponent(simjoint, ignition::gazebo::components::JointPosition());
141 if (!ecm.EntityHasComponentType(
143 ignition::gazebo::components::JointVelocity().TypeId()))
145 ecm.CreateComponent(simjoint, ignition::gazebo::components::JointVelocity());
149 if (!ecm.EntityHasComponentType(
151 ignition::gazebo::components::JointForce().TypeId()))
153 ecm.CreateComponent(simjoint, ignition::gazebo::components::JointForce());
157 ROS_INFO_STREAM(
"[Ignition ROS Control] Loading joint: " << joint_name);
160 this->
dataPtr->joints_[j].joint_position = 0.0;
161 this->
dataPtr->joints_[j].joint_velocity = 0.0;
162 this->
dataPtr->joints_[j].joint_effort = 0.0;
163 this->
dataPtr->joints_[j].joint_effort_cmd = 0.0;
164 this->
dataPtr->joints_[j].joint_position_cmd = 0.0;
165 this->
dataPtr->joints_[j].joint_velocity_cmd = 0.0;
167 std::vector<std::string> joint_interfaces = transmissions[j].joints_[0].hardware_interfaces_;
169 if (joint_interfaces.empty() &&
170 !(transmissions[j].actuators_.empty()) &&
171 !(transmissions[j].actuators_[0].hardware_interfaces_.empty()))
174 joint_interfaces = transmissions[j].actuators_[0].hardware_interfaces_;
175 ROS_WARN_STREAM(
"[Ignition ROS Control] The <hardware_interface> element of tranmission " <<
176 transmissions[j].name_ <<
" should be nested inside the <joint> element, not <actuator>. " <<
177 "The transmission will be properly loaded, but please update " <<
178 "your robot model to remain compatible with future versions of the plugin.");
180 if (joint_interfaces.empty())
182 ROS_WARN_STREAM(
"[Ignition ROS Control] Joint " << transmissions[j].joints_[0].name_ <<
183 " of transmission " << transmissions[j].name_ <<
" does not specify any hardware interface. " <<
184 "Not adding it to the robot hardware simulation.");
187 else if (joint_interfaces.size() > 1)
189 ROS_WARN_STREAM(
"[Ignition ROS Control] Joint " << transmissions[j].joints_[0].name_ <<
190 " of transmission " << transmissions[j].name_ <<
" specifies multiple hardware interfaces. " <<
191 "Currently the default robot hardware simulation interface only supports one. Using the first entry");
199 joint_name, &this->
dataPtr->joints_[j].joint_position, &this->dataPtr->joints_[j].joint_velocity, &this->dataPtr->joints_[j].joint_effort));
208 &this->dataPtr->joints_[j].joint_effort_cmd);
216 &this->dataPtr->joints_[j].joint_position_cmd);
224 &this->dataPtr->joints_[j].joint_velocity_cmd);
235 ROS_WARN_STREAM(
"[Ignition ROS Control] Deprecated syntax, please prepend 'hardware_interface/' to '" <<
hardware_interface <<
"' within the <hardwareInterface> tag in joint '" << joint_name <<
"'.");
250 for (
unsigned int i = 0; i < this->
dataPtr->joints_.size(); ++i) {
252 const auto * jointVelocity =
253 this->
dataPtr->ecm_->Component<ignition::gazebo::components::JointVelocity>(
254 this->
dataPtr->joints_[i].sim_joint);
263 const auto * jointPositions =
264 this->
dataPtr->ecm_->Component<ignition::gazebo::components::JointPosition>(
265 this->
dataPtr->joints_[i].sim_joint);
267 this->
dataPtr->joints_[i].joint_position = jointPositions->Data()[0];
268 this->
dataPtr->joints_[i].joint_velocity = jointVelocity->Data()[0];
276 for (
unsigned int i = 0; i < this->
dataPtr->joints_.size(); ++i) {
278 if (!this->
dataPtr->ecm_->Component<ignition::gazebo::components::JointVelocityCmd>(
279 this->dataPtr->joints_[i].sim_joint))
281 this->
dataPtr->ecm_->CreateComponent(
282 this->
dataPtr->joints_[i].sim_joint,
283 ignition::gazebo::components::JointVelocityCmd({0}));
286 double targetVel = this->
dataPtr->joints_[i].joint_velocity_cmd;
288 this->
dataPtr->ecm_->Component<ignition::gazebo::components::JointVelocityCmd>(
289 this->
dataPtr->joints_[i].sim_joint);
291 if (vel ==
nullptr) {
292 this->
dataPtr->ecm_->CreateComponent(
293 this->
dataPtr->joints_[i].sim_joint,
294 ignition::gazebo::components::JointVelocityCmd({targetVel}));
295 }
else if (!vel->Data().empty()) {
296 vel->Data()[0] = targetVel;
304 error = (this->
dataPtr->joints_[i].joint_position -
305 this->
dataPtr->joints_[i].joint_position_cmd) * this->
dataPtr->update_rate_;
307 double targetVel = -error;
310 this->dataPtr->ecm_->Component<ignition::gazebo::components::JointVelocityCmd>(
311 this->dataPtr->joints_[i].sim_joint);
313 if (vel ==
nullptr) {
314 this->
dataPtr->ecm_->CreateComponent(
315 this->
dataPtr->joints_[i].sim_joint,
316 ignition::gazebo::components::JointVelocityCmd({targetVel}));
317 }
else if (!vel->Data().empty()) {
318 vel->Data()[0] = targetVel;
322 if (this->
dataPtr->joints_[i].joint_control_method ==
EFFORT) {
323 if (!this->
dataPtr->ecm_->Component<ignition::gazebo::components::JointForceCmd>(
324 this->dataPtr->joints_[i].sim_joint))
326 this->
dataPtr->ecm_->CreateComponent(
327 this->
dataPtr->joints_[i].sim_joint,
328 ignition::gazebo::components::JointForceCmd({0}));
330 const auto jointEffortCmd =
331 this->
dataPtr->ecm_->Component<ignition::gazebo::components::JointForceCmd>(
332 this->
dataPtr->joints_[i].sim_joint);
333 *jointEffortCmd = ignition::gazebo::components::JointForceCmd(
334 {this->
dataPtr->joints_[i].joint_effort_cmd});