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 
391 
392  // TODO(lucasw) store an Ogre::ColorValue and set it according to joint type.
393  axis_->setColor(0.0, 0.8, 0.0, 1.0);
394  }
395  }
396  else
397  {
398  if (axis_)
399  {
400  delete axis_;
401  axis_ = nullptr;
402  }
403  }
404 }
405 
406 void RobotJoint::setTransforms(const Ogre::Vector3& parent_link_position,
407  const Ogre::Quaternion& parent_link_orientation)
408 {
409  Ogre::Vector3 position = parent_link_position + parent_link_orientation * joint_origin_pos_;
410  Ogre::Quaternion orientation = parent_link_orientation * joint_origin_rot_;
411 
412  position_property_->setVector(position);
413  orientation_property_->setQuaternion(orientation);
414 
415  if (axes_)
416  {
417  axes_->setPosition(position);
418  axes_->setOrientation(orientation);
419  }
420  if (axis_)
421  {
422  axis_->setPosition(position);
423  axis_->setDirection(orientation * axis_property_->getVector());
424  }
425 }
426 
428 {
431  axes_property_->setHidden(hide);
433  axis_property_->setHidden(hide);
434 }
435 
436 Ogre::Vector3 RobotJoint::getPosition()
437 {
438  return position_property_->getVector();
439 }
440 
441 Ogre::Quaternion RobotJoint::getOrientation()
442 {
444 }
445 
447 {
448  Property* old_parent = joint_property_->getParent();
449  if (old_parent)
450  old_parent->takeChild(joint_property_);
451 
452  if (new_parent)
453  new_parent->addChild(joint_property_);
454 }
455 
456 // if use_detail:
457 // - all sub properties become children of details_ property.
458 // - details_ property becomes a child of joint_property_
459 // else (!use_detail)
460 // - all sub properties become children of joint_property_.
461 // details_ property does not have a parent.
462 void RobotJoint::useDetailProperty(bool use_detail)
463 {
464  Property* old_parent = details_->getParent();
465  if (old_parent)
466  old_parent->takeChild(details_);
467 
468  if (use_detail)
469  {
470  while (joint_property_->numChildren() > 0)
471  {
472  Property* child = joint_property_->childAt(0);
473  joint_property_->takeChild(child);
474  details_->addChild(child);
475  }
476 
478  }
479  else
480  {
481  while (details_->numChildren() > 0)
482  {
483  Property* child = details_->childAt(0);
484  details_->takeChild(child);
485  joint_property_->addChild(child);
486  }
487  }
488 }
489 
490 void RobotJoint::expandDetails(bool expand)
491 {
493  if (expand)
494  {
495  parent->expand();
496  }
497  else
498  {
499  parent->collapse();
500  }
501 }
502 
503 } // 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:564
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:572
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:552
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 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:436
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 Sat May 27 2023 02:06:25