Gazebo Rendering

API Reference

7.4.2
gz/rendering/base/BaseJointVisual.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2021 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 #ifndef GZ_RENDERING_BASE_BASEJOINTVISUAL_HH_
18 #define GZ_RENDERING_BASE_BASEJOINTVISUAL_HH_
19 
20 #include <algorithm>
21 #include <string>
22 
23 #include "gz/common/Console.hh"
24 
28 #include "gz/rendering/Scene.hh"
31 
32 namespace gz
33 {
34  namespace rendering
35  {
36  inline namespace GZ_RENDERING_VERSION_NAMESPACE {
37  //
39  template <class T>
41  public virtual JointVisual,
42  public virtual T
43  {
45  protected: BaseJointVisual();
46 
48  public: virtual ~BaseJointVisual();
49 
50  // Documentation inherited.
51  protected: virtual void Init() override;
52 
53  // Documentation inherited.
54  protected: virtual void PreRender() override;
55 
56  // Documentation inherited.
57  protected: virtual void Destroy() override;
58 
59  // Documentation inherited.
60  public: virtual void SetAxis(const gz::math::Vector3d &_axis,
61  bool _useParentFrame) override;
62 
63  // Documentation inherited.
64  public: virtual gz::math::Vector3d Axis() const override;
65 
66  // Documentation inherited.
67  public: virtual void SetParentAxis(
68  const gz::math::Vector3d &_axis,
69  const std::string &_parentName,
70  bool _useParentFrame) override;
71 
72  // Documentation inherited.
73  public: virtual gz::math::Vector3d ParentAxis() const override;
74 
75  // Documentation inherited.
76  public: virtual bool UpdateAxis(const gz::math::Vector3d &_axis,
77  bool _useParentFrame) override;
78 
79  // Documentation inherited.
80  public: virtual bool UpdateParentAxis(
81  const gz::math::Vector3d &_axis,
82  bool _useParentFrame) override;
83 
84  // Documentation inherited.
85  public: virtual void SetType(const JointVisualType _type) override;
86 
87  // Documentation inherited.
88  public: virtual JointVisualType Type() const override;
89 
90  // Documentation inherited.
91  public: virtual JointVisualPtr ParentAxisVisual() const override;
92 
93  // Documentation inherited.
94  public: virtual ArrowVisualPtr ArrowVisual() const override;
95 
96  // Documentation inherited.
97  public: virtual void SetVisible(bool _visible) override;
98 
104  protected: void UpdateAxisImpl(ArrowVisualPtr _arrowVisual,
105  const gz::math::Vector3d &_axis,
106  bool _useParentFrame);
107 
109  protected: void CreateAxis();
110 
112  protected: void CreateParentAxis();
113 
115  protected: void ScaleToChild();
116 
118  protected: JointVisualType jointVisualType =
120 
122  protected: AxisVisualPtr axisVisual = nullptr;
123 
127  protected: ArrowVisualPtr arrowVisual = nullptr;
128 
131  protected: JointVisualPtr parentAxisVis = nullptr;
132 
134  protected: gz::math::Vector3d scaleToChild =
136 
138  protected: bool dirtyJointType = false;
139 
141  protected: bool dirtyAxis = false;
142 
144  protected: bool dirtyParentAxis = false;
145 
147  protected: gz::math::Vector3d axis =
149 
152  protected: bool useParentFrame = false;
153 
155  protected: bool updateAxis = false;
156 
158  protected: gz::math::Vector3d parentAxis =
160 
162  protected: std::string jointParentName = "";
163 
166  protected: bool parentAxisUseParentFrame = false;
167 
169  protected: bool updateParentAxis = false;
170  };
171 
173  template <class T>
175  {
176  }
177 
179  template <class T>
181  {
182  }
183 
185  template <class T>
187  {
188  T::PreRender();
189 
190  if (this->ParentAxisVisual())
191  {
192  this->ParentAxisVisual()->PreRender();
193  }
194 
195  if (this->dirtyJointType)
196  {
197  this->UpdateAxis(this->axis, this->useParentFrame);
198  this->UpdateParentAxis(this->parentAxis,
199  this->parentAxisUseParentFrame);
200 
201  this->dirtyJointType = false;
202  }
203 
204  if (this->dirtyAxis)
205  {
206  this->CreateAxis();
207  this->dirtyAxis = false;
208  }
209 
210  if (this->dirtyParentAxis)
211  {
212  this->CreateParentAxis();
213  this->dirtyParentAxis = false;
214  }
215 
216  if (this->updateAxis)
217  {
218  this->updateAxis =
219  !this->UpdateAxis(this->axis, this->useParentFrame);
220  }
221 
222  if (this->updateParentAxis)
223  {
224  this->updateParentAxis =
225  !this->UpdateParentAxis(this->parentAxis,
226  this->parentAxisUseParentFrame);
227  }
228  }
229 
231  template <class T>
233  {
234  T::Init();
235 
236  this->axisVisual = this->Scene()->CreateAxisVisual();
237  this->AddChild(this->axisVisual);
238  this->SetInheritScale(false);
239  }
240 
242  template <class T>
244  {
245  if (this->arrowVisual != nullptr)
246  {
247  this->arrowVisual->Destroy();
248  this->arrowVisual.reset();
249  }
250 
251  if (this->axisVisual != nullptr)
252  {
253  this->axisVisual->Destroy();
254  this->axisVisual.reset();
255  }
256 
257  if (this->parentAxisVis != nullptr)
258  {
259  this->parentAxisVis->Destroy();
260  this->parentAxisVis.reset();
261  }
262 
263  this->dirtyJointType = false;
264  this->dirtyAxis = false;
265  this->dirtyParentAxis = false;
266 
267  T::Destroy();
268  }
269 
271  template <class T>
273  const gz::math::Vector3d &_axis,
274  bool _useParentFrame)
275  {
276  this->axis = _axis;
277  this->useParentFrame = _useParentFrame;
278  this->dirtyAxis = true;
279  }
280 
282  template <class T>
284  {
285  if (this->arrowVisual)
286  {
287  this->arrowVisual->Destroy();
288  this->arrowVisual.reset();
289  }
290 
291  this->arrowVisual = this->Scene()->CreateArrowVisual();
292  this->arrowVisual->SetMaterial("Default/TransYellow");
293  this->arrowVisual->SetLocalPosition(0, 0, 0);
294  this->arrowVisual->SetLocalRotation(0, 0, 0);
295  this->AddChild(this->arrowVisual);
296 
297  this->updateAxis = true;
298  this->ScaleToChild();
299  }
300 
302  template <class T>
304  const gz::math::Vector3d &_axis,
305  const std::string &_parentName,
306  bool _useParentFrame)
307  {
308  if (this->Type() != JointVisualType::JVT_REVOLUTE2 &&
309  this->Type() != JointVisualType::JVT_UNIVERSAL)
310  {
311  gzlog << "Joint visual is not of type Revolute2 or "
312  << " Universal "
313  << " so the parent axis will not be shown\n";
314  return;
315  }
316 
317  this->parentAxis = _axis;
318  this->parentAxisUseParentFrame = _useParentFrame;
319  this->jointParentName = _parentName;
320  this->dirtyParentAxis = true;
321  }
322 
324  template <class T>
326  {
327  auto jointParentVis = this->Scene()->NodeByName(this->jointParentName);
328  if (jointParentVis == nullptr)
329  {
330  gzlog << "Joint parent with name " << this->jointParentName
331  << " does not exist"
332  << " so the parent axis will not be shown\n";
333  return;
334  }
335 
336  if (this->parentAxisVis)
337  {
338  this->parentAxisVis->Destroy();
339  this->parentAxisVis.reset();
340  }
341 
342  this->parentAxisVis = this->Scene()->CreateJointVisual();
343  jointParentVis->AddChild(this->parentAxisVis);
344  this->parentAxisVis->SetType(this->Type());
345  this->parentAxisVis->SetAxis(this->parentAxis,
346  this->parentAxisUseParentFrame);
347 
348  this->updateParentAxis = true;
349  this->ScaleToChild();
350  }
351 
353  template <class T>
355  bool _useParentFrame)
356  {
357  if (this->ArrowVisual() && this->HasParent())
358  {
359  this->UpdateAxisImpl(this->ArrowVisual(), _axis, _useParentFrame);
360  return true;
361  }
362 
363  return false;
364  }
365 
367  template <class T>
369  const gz::math::Vector3d &_axis,
370  bool _useParentFrame)
371  {
372  if (this->ParentAxisVisual() &&
373  this->ParentAxisVisual()->ArrowVisual() &&
374  this->ParentAxisVisual()->HasParent())
375  {
376  this->UpdateAxisImpl(this->ParentAxisVisual()->ArrowVisual(),
377  _axis, _useParentFrame);
378  return true;
379  }
380 
381  return false;
382  }
383 
385  template <class T>
387  const gz::math::Vector3d &_axis,
388  bool _useParentFrame)
389  {
390  // Get rotation to axis vector
391  gz::math::Vector3d axisDir = _axis;
392  gz::math::Vector3d u = axisDir.Normalize();
394  double cosTheta = v.Dot(u);
395  double angle = acos(cosTheta);
397  // check the parallel case
398  if (gz::math::equal(angle, GZ_PI))
399  quat.SetFromAxisAngle(u.Perpendicular(), angle);
400  else
401  quat.SetFromAxisAngle((v.Cross(u)).Normalize(), angle);
402  _arrowVisual->SetLocalRotation(quat);
403 
404  if (_useParentFrame)
405  {
406  gz::math::Pose3d parentInitPose =
407  this->Parent()->InitialLocalPose();
408 
409  // get rotation of joint visual in model frame
410  gz::math::Quaterniond quatFromModel =
411  (parentInitPose * this->LocalPose()).Rot();
412 
413  // rotate arrow visual so that the axis vector applies to the model
414  // frame.
415  _arrowVisual->SetLocalRotation(quatFromModel.Inverse() *
416  _arrowVisual->LocalRotation());
417  }
418 
419  _arrowVisual->ShowArrowRotation(
420  this->Type() == JointVisualType::JVT_REVOLUTE ||
421  this->Type() == JointVisualType::JVT_REVOLUTE2 ||
422  this->Type() == JointVisualType::JVT_UNIVERSAL ||
423  this->Type() == JointVisualType::JVT_GEARBOX);
424 
425  if (this->axisVisual)
426  _arrowVisual->SetVisible(true);
427  else
428  return;
429 
430  // Don't change the visibility of joint child axis
431  if (this->ArrowVisual() != _arrowVisual)
432  return;
433 
434  // Hide existing arrow head if it overlaps with the axis
435  auto axisWorldRotation = _arrowVisual->WorldPose().Rot();
436  auto jointWorldRotation = this->WorldPose().Rot();
437 
438  this->axisVisual->ShowAxisHead(true);
439  _arrowVisual->ShowArrowShaft(true);
440 
441  auto axisWorld = axisWorldRotation * gz::math::Vector3d::UnitZ;
442  if (axisWorld == jointWorldRotation * gz::math::Vector3d::UnitX)
443  {
444  this->axisVisual->ShowAxisHead(0, false);
445  _arrowVisual->ShowArrowShaft(false);
446  }
447  else if (axisWorld ==
448  jointWorldRotation * gz::math::Vector3d::UnitY)
449  {
450  this->axisVisual->ShowAxisHead(1, false);
451  _arrowVisual->ShowArrowShaft(false);
452  }
453  else if (axisWorld ==
454  jointWorldRotation * gz::math::Vector3d::UnitZ)
455  {
456  this->axisVisual->ShowAxisHead(2, false);
457  _arrowVisual->ShowArrowShaft(false);
458  }
459  }
460 
462  template <class T>
464  {
465  if (!this->HasParent())
466  return;
467 
468  // Joint visual is attached to the child's visual
469  VisualPtr parentVisual =
470  std::dynamic_pointer_cast<Visual>(this->Parent());
471 
472  if (parentVisual)
473  {
474  double childSize =
475  std::max(0.1, parentVisual->BoundingBox().Size().Length());
476  this->scaleToChild = gz::math::Vector3d(childSize * 0.2,
477  childSize * 0.2, childSize * 0.2);
478  this->SetLocalScale(this->scaleToChild);
479  if (this->ParentAxisVisual())
480  this->ParentAxisVisual()->SetLocalScale(this->scaleToChild);
481  }
482  }
483 
485  template <class T>
487  {
488  this->jointVisualType = _type;
489  this->dirtyJointType = true;
490  }
491 
493  template <class T>
495  {
496  return this->axis;
497  }
498 
500  template <class T>
502  {
503  return this->parentAxis;
504  }
505 
507  template <class T>
509  {
510  return this->jointVisualType;
511  }
512 
514  template <class T>
516  {
517  return this->parentAxisVis;
518  }
519 
521  template <class T>
523  {
524  return this->arrowVisual;
525  }
526 
528  template <class T>
529  void BaseJointVisual<T>::SetVisible(bool _visible)
530  {
531  T::SetVisible(_visible);
532 
533  if (this->ArrowVisual())
534  this->ArrowVisual()->SetVisible(_visible);
535 
536  if (this->Type() == JointVisualType::JVT_REVOLUTE2 ||
537  this->Type() == JointVisualType::JVT_UNIVERSAL)
538  {
539  if (this->ParentAxisVisual())
540  this->ParentAxisVisual()->SetVisible(_visible);
541  }
542 
543  if (this->axisVisual)
544  this->axisVisual->SetVisible(_visible);
545  }
546  }
547  }
548 }
549 #endif