Gazebo Rendering

API Reference

9.0.0
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
32namespace 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 =
119 JointVisualType::JVT_NONE;
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>
177
179 template <class T>
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>
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