robot_joint.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "rviz/robot/robot_joint.h"
31 #include "rviz/robot/robot_link.h"
32 #include "rviz/robot/robot.h"
33 
34 #include <OgreSceneNode.h>
35 
41 #include "rviz/ogre_helpers/axes.h"
42 #include "rviz/load_resource.h"
43 
44 namespace rviz
45 {
46 RobotJoint::RobotJoint(Robot* robot, const urdf::JointConstSharedPtr& joint)
47  : robot_(robot)
48  , name_(joint->name)
49  , parent_link_name_(joint->parent_link_name)
50  , child_link_name_(joint->child_link_name)
51  , has_decendent_links_with_geometry_(true)
52  , doing_set_checkbox_(false)
53  , axes_(nullptr)
54  , axis_(nullptr)
55 {
56  joint_property_ = new Property(name_.c_str(), true, "", nullptr, SLOT(updateChildVisibility()), this);
57  joint_property_->setIcon(rviz::loadPixmap("package://rviz/icons/classes/RobotJoint.png"));
58 
59  details_ = new Property("Details", QVariant(), "", nullptr);
60 
61  axes_property_ = new Property("Show Axes", false, "Enable/disable showing the axes of this joint.",
62  joint_property_, SLOT(updateAxes()), this);
63 
65  new VectorProperty("Position", Ogre::Vector3::ZERO,
66  "Position of this joint, in the current Fixed Frame. (Not editable)",
69 
71  new QuaternionProperty("Orientation", Ogre::Quaternion::IDENTITY,
72  "Orientation of this joint, in the current Fixed Frame. (Not editable)",
75 
76  std::string type = "";
77  if (joint->type == urdf::Joint::UNKNOWN)
78  type = "unknown";
79  else if (joint->type == urdf::Joint::REVOLUTE)
80  type = "revolute";
81  else if (joint->type == urdf::Joint::CONTINUOUS)
82  type = "continuous";
83  else if (joint->type == urdf::Joint::PRISMATIC)
84  type = "prismatic";
85  else if (joint->type == urdf::Joint::FLOATING)
86  type = "floating";
87  else if (joint->type == urdf::Joint::PLANAR)
88  type = "planar";
89  else if (joint->type == urdf::Joint::FIXED)
90  type = "fixed";
91 
92  type_property_ = new StringProperty("Type", QString::fromStdString(type),
93  "Type of this joint. (Not editable)", joint_property_);
95 
96  if (joint->limits)
97  {
98  // continuous joints have lower limit and upper limits of zero,
99  // which means this isn't very useful but show it anyhow.
101  new FloatProperty("Lower Limit", joint->limits->lower,
102  "Lower limit of this joint. (Not editable)", joint_property_);
104 
106  new FloatProperty("Upper Limit", joint->limits->upper,
107  "Upper limit of this joint. (Not editable)", joint_property_);
109  }
110 
111  if ((type == "continuous") || (type == "revolute") || (type == "prismatic") || (type == "planar"))
112  {
114  new Property("Show Joint Axis", false, "Enable/disable showing the axis of this joint.",
115  joint_property_, SLOT(updateAxis()), this);
116 
118  new VectorProperty("Joint Axis", Ogre::Vector3(joint->axis.x, joint->axis.y, joint->axis.z),
119  "Axis of this joint. (Not editable)", joint_property_);
121  }
122 
124 
125  const urdf::Vector3& pos = joint->parent_to_joint_origin_transform.position;
126  const urdf::Rotation& rot = joint->parent_to_joint_origin_transform.rotation;
127  joint_origin_pos_ = Ogre::Vector3(pos.x, pos.y, pos.z);
128  joint_origin_rot_ = Ogre::Quaternion(rot.w, rot.x, rot.y, rot.z);
129 }
130 
132 {
133  delete axes_;
134  if (axis_)
135  delete axis_;
136  delete details_;
137  delete joint_property_;
138 }
139 
141 {
142  int links_with_geom;
143  int links_with_geom_checked;
144  int links_with_geom_unchecked;
145  getChildLinkState(links_with_geom, links_with_geom_checked, links_with_geom_unchecked, true);
146 
147  std::stringstream desc;
148  desc << "Joint <b>" << name_ << "</b> with parent link <b>" << parent_link_name_
149  << "</b> and child link <b>" << child_link_name_ << "</b>.";
150 
151  if (links_with_geom == 0)
152  {
153  desc << " This joint's descendents have NO geometry.";
154  setJointCheckbox(QVariant());
156  }
157  else if (styleIsTree())
158  {
159  desc << " Check/uncheck to show/hide all links descended from this joint.";
160  setJointCheckbox(links_with_geom_unchecked == 0);
162  }
163  else
164  {
165  getChildLinkState(links_with_geom, links_with_geom_checked, links_with_geom_unchecked, false);
166  if (links_with_geom == 0)
167  {
168  desc << " This joint's child link has NO geometry.";
169  setJointCheckbox(QVariant());
171  }
172  else
173  {
174  desc << " Check/uncheck to show/hide this joint's child link.";
175  setJointCheckbox(links_with_geom_unchecked == 0);
177  }
178  }
179 
180  joint_property_->setDescription(desc.str().c_str());
181 }
182 
184 {
185  // setting doing_set_checkbox_ to true prevents updateChildVisibility() from
186  // updating child link enables.
187  doing_set_checkbox_ = true;
189  doing_set_checkbox_ = false;
190 }
191 
193 {
194  RobotLink* parent_link = robot_->getLink(parent_link_name_);
195  if (!parent_link)
196  return nullptr;
197 
198  const std::string& parent_joint_name = parent_link->getParentJointName();
199  if (parent_joint_name.empty())
200  return nullptr;
201 
202  return robot_->getJoint(parent_joint_name);
203 }
204 
206  int& links_with_geom_checked,
207  int& links_with_geom_unchecked)
208 {
209  links_with_geom_checked = 0;
210  links_with_geom_unchecked = 0;
211 
213  if (link && link->hasGeometry())
214  {
215  bool checked = link->getLinkProperty()->getValue().toBool();
216  links_with_geom_checked += checked ? 1 : 0;
217  links_with_geom_unchecked += checked ? 0 : 1;
218  }
219  links_with_geom = links_with_geom_checked + links_with_geom_unchecked;
220 
221  if (!styleIsTree())
222  {
223  if (!links_with_geom)
224  {
225  setJointCheckbox(QVariant());
226  }
227  else
228  {
229  setJointCheckbox(links_with_geom_unchecked == 0);
230  }
231  }
232 
233  std::vector<std::string>::const_iterator child_joint_it = link->getChildJointNames().begin();
234  std::vector<std::string>::const_iterator child_joint_end = link->getChildJointNames().end();
235  for (; child_joint_it != child_joint_end; ++child_joint_it)
236  {
237  RobotJoint* child_joint = robot_->getJoint(*child_joint_it);
238  if (child_joint)
239  {
240  int child_links_with_geom;
241  int child_links_with_geom_checked;
242  int child_links_with_geom_unchecked;
244  child_links_with_geom, child_links_with_geom_checked, child_links_with_geom_unchecked);
245  links_with_geom_checked += child_links_with_geom_checked;
246  links_with_geom_unchecked += child_links_with_geom_unchecked;
247  }
248  }
249  links_with_geom = links_with_geom_checked + links_with_geom_unchecked;
250 
251  if (styleIsTree())
252  {
253  if (!links_with_geom)
254  {
255  setJointCheckbox(QVariant());
256  }
257  else
258  {
259  setJointCheckbox(links_with_geom_unchecked == 0);
260  }
261  }
262 }
263 
264 
265 void RobotJoint::getChildLinkState(int& links_with_geom,
266  int& links_with_geom_checked,
267  int& links_with_geom_unchecked,
268  bool recursive) const
269 {
270  links_with_geom_checked = 0;
271  links_with_geom_unchecked = 0;
272 
274  if (link && link->hasGeometry())
275  {
276  bool checked = link->getLinkProperty()->getValue().toBool();
277  links_with_geom_checked += checked ? 1 : 0;
278  links_with_geom_unchecked += checked ? 0 : 1;
279  }
280 
281  if (recursive)
282  {
283  std::vector<std::string>::const_iterator child_joint_it = link->getChildJointNames().begin();
284  std::vector<std::string>::const_iterator child_joint_end = link->getChildJointNames().end();
285  for (; child_joint_it != child_joint_end; ++child_joint_it)
286  {
287  RobotJoint* child_joint = robot_->getJoint(*child_joint_it);
288  if (child_joint)
289  {
290  int child_links_with_geom;
291  int child_links_with_geom_checked;
292  int child_links_with_geom_unchecked;
293  child_joint->getChildLinkState(child_links_with_geom, child_links_with_geom_checked,
294  child_links_with_geom_unchecked, recursive);
295  links_with_geom_checked += child_links_with_geom_checked;
296  links_with_geom_unchecked += child_links_with_geom_unchecked;
297  }
298  }
299  }
300 
301  links_with_geom = links_with_geom_checked + links_with_geom_unchecked;
302 }
303 
304 
306 {
308  return true;
309  return joint_property_->getValue().toBool();
310 }
311 
313 {
314  return details_->getParent() != nullptr;
315 }
316 
318 {
320  return;
321 
323  return;
324 
325  bool visible = getEnabled();
326 
328  if (link)
329  {
330  if (link->hasGeometry())
331  {
332  link->getLinkProperty()->setValue(visible);
333  }
334 
335  if (styleIsTree())
336  {
337  std::vector<std::string>::const_iterator child_joint_it = link->getChildJointNames().begin();
338  std::vector<std::string>::const_iterator child_joint_end = link->getChildJointNames().end();
339  for (; child_joint_it != child_joint_end; ++child_joint_it)
340  {
341  RobotJoint* child_joint = robot_->getJoint(*child_joint_it);
342  if (child_joint)
343  {
344  child_joint->getJointProperty()->setValue(visible);
345  }
346  }
347  }
348  }
349 }
350 
352 {
353  if (axes_property_->getValue().toBool())
354  {
355  if (!axes_)
356  {
357  static int count = 0;
358  std::stringstream ss;
359  ss << "Axes for joint " << name_ << count++;
360  axes_ = new Axes(robot_->getSceneManager(), robot_->getOtherNode(), 0.1, 0.01);
361  axes_->getSceneNode()->setVisible(getEnabled());
362 
365  }
366  }
367  else
368  {
369  if (axes_)
370  {
371  delete axes_;
372  axes_ = nullptr;
373  }
374  }
375 }
376 
378 {
379  if (show_axis_property_->getValue().toBool())
380  {
381  if (!axis_)
382  {
383  static int count = 0;
384  std::stringstream ss;
385  ss << "Axis for joint " << name_ << count++;
386  axis_ = new Arrow(robot_->getSceneManager(), robot_->getOtherNode(), 0.15, 0.05, 0.05, 0.08);
387  axis_->getSceneNode()->setVisible(getEnabled());
388 
390  Ogre::Quaternion q = orientation_property_->getQuaternion();
391  axis_->setOrientation(q);
392 
393  q = q * joint_origin_rot_.UnitInverse(); // parent_link_orientation
395 
396  // TODO(lucasw) store an Ogre::ColorValue and set it according to
397  // joint type.
398  axis_->setColor(0.0, 0.8, 0.0, 1.0);
399  }
400  }
401  else
402  {
403  if (axis_)
404  {
405  delete axis_;
406  axis_ = nullptr;
407  }
408  }
409 }
410 
411 void RobotJoint::setTransforms(const Ogre::Vector3& parent_link_position,
412  const Ogre::Quaternion& parent_link_orientation)
413 {
414  Ogre::Vector3 position = parent_link_position + parent_link_orientation * joint_origin_pos_;
415  Ogre::Quaternion orientation = parent_link_orientation * joint_origin_rot_;
416 
417  position_property_->setVector(position);
418  orientation_property_->setQuaternion(orientation);
419 
420  if (axes_)
421  {
422  axes_->setPosition(position);
423  axes_->setOrientation(orientation);
424  }
425  if (axis_)
426  {
427  axis_->setPosition(position);
428  axis_->setOrientation(orientation);
429  axis_->setDirection(parent_link_orientation * axis_property_->getVector());
430  }
431 }
432 
434 {
437  axes_property_->setHidden(hide);
439  axis_property_->setHidden(hide);
440 }
441 
442 Ogre::Vector3 RobotJoint::getPosition()
443 {
444  return position_property_->getVector();
445 }
446 
447 Ogre::Quaternion RobotJoint::getOrientation()
448 {
450 }
451 
453 {
454  Property* old_parent = joint_property_->getParent();
455  if (old_parent)
456  old_parent->takeChild(joint_property_);
457 
458  if (new_parent)
459  new_parent->addChild(joint_property_);
460 }
461 
462 // if use_detail:
463 // - all sub properties become children of details_ property.
464 // - details_ property becomes a child of joint_property_
465 // else (!use_detail)
466 // - all sub properties become children of joint_property_.
467 // details_ property does not have a parent.
468 void RobotJoint::useDetailProperty(bool use_detail)
469 {
470  Property* old_parent = details_->getParent();
471  if (old_parent)
472  old_parent->takeChild(details_);
473 
474  if (use_detail)
475  {
476  while (joint_property_->numChildren() > 0)
477  {
478  Property* child = joint_property_->childAt(0);
479  joint_property_->takeChild(child);
480  details_->addChild(child);
481  }
482 
484  }
485  else
486  {
487  while (details_->numChildren() > 0)
488  {
489  Property* child = details_->childAt(0);
490  details_->takeChild(child);
491  joint_property_->addChild(child);
492  }
493  }
494 }
495 
496 void RobotJoint::expandDetails(bool expand)
497 {
499  if (expand)
500  {
501  parent->expand();
502  }
503  else
504  {
505  parent->collapse();
506  }
507 }
508 
509 } // namespace rviz
void setParentProperty(Property *new_parent)
bool styleIsTree() const
VectorProperty * axis_property_
Definition: robot_joint.h:189
const Property * getJointProperty() const
Definition: robot_joint.h:107
void setOrientation(const Ogre::Quaternion &orientation) override
Set the orientation of the object.
Definition: axes.cpp:88
StringProperty * type_property_
Definition: robot_joint.h:191
void setJointPropertyDescription()
Ogre::Quaternion joint_origin_rot_
Definition: robot_joint.h:197
void updateChildVisibility()
Property * details_
Definition: robot_joint.h:184
virtual void expand()
Expand (show the children of) this Property.
Definition: property.cpp:555
virtual bool setVector(const Ogre::Vector3 &vector)
void useDetailProperty(bool use_detail)
void hideSubProperties(bool hide)
QuaternionProperty * orientation_property_
Definition: robot_joint.h:186
Ogre::SceneNode * getOtherNode()
Definition: robot.h:180
Property * getParent() const
Return the parent Property.
Definition: property.cpp:231
void setDirection(const Ogre::Vector3 &direction)
Set the direction of the arrow.
Definition: arrow.cpp:126
void setPosition(const Ogre::Vector3 &position) override
Set the position of the base of the arrow.
Definition: arrow.cpp:114
virtual bool setValue(const QVariant &new_value)
Set the new value for this property. Returns true if the new value is different from the old value...
Definition: property.cpp:134
std::string parent_link_name_
Definition: robot_joint.h:179
A single element of a property tree, with a name, value, description, and possibly children...
Definition: property.h:100
Ogre::SceneManager * getSceneManager()
Definition: robot.h:184
bool hasDescendentLinksWithGeometry() const
Definition: robot_joint.h:129
void calculateJointCheckboxesRecursive(int &links_with_geom, int &links_with_geom_checked, int &links_with_geom_unchecked)
void setReadOnly(bool read_only) override
Overridden from Property to propagate read-only-ness to children.
Property * joint_property_
Definition: robot_joint.h:183
virtual Ogre::Vector3 getVector() const
Ogre::Vector3 joint_origin_pos_
Definition: robot_joint.h:196
void setTransforms(const Ogre::Vector3 &parent_link_position, const Ogre::Quaternion &parent_link_orientation)
Property specialized to enforce floating point max/min.
VectorProperty * position_property_
Definition: robot_joint.h:185
void setReadOnly(bool read_only) override
Overridden from Property to propagate read-only-ness to children.
virtual void setDescription(const QString &description)
Set the description.
Definition: property.cpp:169
RobotLink * getLink(const std::string &name)
Definition: robot.cpp:622
Ogre::SceneNode * getSceneNode()
Get the scene node associated with this arrow.
Definition: arrow.h:149
Property * takeChild(Property *child)
Remove a given child object and return a pointer to it.
Definition: property.cpp:321
Property * show_axis_property_
Definition: robot_joint.h:190
virtual void collapse()
Collapse (hide the children of) this Property.
Definition: property.cpp:563
virtual void setIcon(const QIcon &icon)
Set the icon to be displayed next to the property.
Definition: property.h:193
Property * axes_property_
Definition: robot_joint.h:187
RobotJoint(Robot *robot, const urdf::JointConstSharedPtr &joint)
Definition: robot_joint.cpp:46
bool doing_set_checkbox_
Definition: robot_joint.h:200
FloatProperty * upper_limit_property_
Definition: robot_joint.h:193
virtual bool setQuaternion(const Ogre::Quaternion &quaternion)
Ogre::Vector3 getPosition()
void setJointCheckbox(QVariant val)
std::string name_
Name of this joint.
Definition: robot_joint.h:178
Contains any data we need from a joint in the robot.
Definition: robot_joint.h:84
void expandDetails(bool expand)
An object that displays a set of X/Y/Z axes, with X=Red, Y=Green, Z=Blue.
Definition: axes.h:59
void setPosition(const Ogre::Vector3 &position) override
Set the position of this object.
Definition: axes.cpp:83
FloatProperty * lower_limit_property_
Definition: robot_joint.h:192
virtual void setHidden(bool hidden)
Hide or show this property in any PropertyTreeWidget viewing its parent.
Definition: property.cpp:543
Property specialized for string values.
virtual int numChildren() const
Return the number of child objects (Property or otherwise).
Definition: property.h:227
std::string child_link_name_
Definition: robot_joint.h:180
Property * childAt(int index) const
Return the child Property with the given index, or NULL if the index is out of bounds or if the child...
Definition: property.cpp:202
virtual void addChild(Property *child, int index=-1)
Add a child property.
Definition: property.cpp:355
bool getEnabled() const
RobotJoint * getParentJoint()
An arrow consisting of a cylinder and a cone.
Definition: arrow.h:59
void setOrientation(const Ogre::Quaternion &orientation) override
Set the orientation.
Definition: arrow.cpp:119
void setColor(float r, float g, float b, float a) override
Set the color of this arrow. Sets both the head and shaft color to the same value. Values are in the range [0, 1].
Definition: arrow.cpp:89
virtual QVariant getValue() const
Return the value of this Property as a QVariant. If the value has never been set, an invalid QVariant...
Definition: property.cpp:150
Ogre::SceneNode * getSceneNode()
Get the scene node associated with this object.
Definition: axes.h:95
Ogre::Quaternion getOrientation()
void getChildLinkState(int &links_with_geom, int &links_with_geom_checked, int &links_with_geom_unchecked, bool recursive) const
virtual void setReadOnly(bool read_only)
Prevent or allow users to edit this property from a PropertyTreeWidget.
Definition: property.h:433
QPixmap loadPixmap(QString url, bool fill_cache)
~RobotJoint() override
virtual Ogre::Quaternion getQuaternion() const
bool has_decendent_links_with_geometry_
Definition: robot_joint.h:198
RobotJoint * getJoint(const std::string &name)
Definition: robot.cpp:634


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Fri Feb 3 2023 03:06:42