Skip to content

Joint visual #366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 35 commits into from
Aug 19, 2021
Merged

Joint visual #366

merged 35 commits into from
Aug 19, 2021

Conversation

atharva-18
Copy link
Contributor

@atharva-18 atharva-18 commented Jul 19, 2021

🎉 New feature

Summary

Adds joint visual consisting of an axis and an arrow visual.
Gazebo Classic's implementation can be found here - https://github.com/osrf/gazebo/blob/gazebo11/gazebo/rendering/JointVisual.cc
joint_visual

Test it

I have added an example in the visualization_demo folder.
To test it with Ignition Gazebo use the visualize_joints branch.

Checklist

  • Signed all commits for DCO
  • Added tests
  • Added example and/or tutorial
  • Updated documentation (as needed)
  • Updated migration guide (as needed)
  • codecheck passed (See contributing)
  • All tests passed (See test coverage)
  • While waiting for a review on your PR, please help review another open pull request to support the maintainers

Note to maintainers: Remember to use Squash-Merge

Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
@atharva-18 atharva-18 requested a review from iche033 as a code owner July 19, 2021 15:47
@github-actions github-actions bot added the 🏯 fortress Ignition Fortress label Jul 19, 2021
Comment on lines 20 to 25
#include <string>
#include <ignition/math/Vector3.hh>
#include "ignition/rendering/config.hh"
#include "ignition/rendering/Object.hh"
#include "ignition/rendering/RenderTypes.hh"
#include "ignition/rendering/Visual.hh"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include <string>
#include <ignition/math/Vector3.hh>
#include "ignition/rendering/config.hh"
#include "ignition/rendering/Object.hh"
#include "ignition/rendering/RenderTypes.hh"
#include "ignition/rendering/Visual.hh"
#include <string>
#include <ignition/math/Vector3.hh>
#include "ignition/rendering/config.hh"
#include "ignition/rendering/Object.hh"
#include "ignition/rendering/RenderTypes.hh"
#include "ignition/rendering/Visual.hh"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const std::string &_xyzExpressedIn) = 0;

/// \brief Update the parent axis' arrow visual if it exists.
/// \param[in] _arrowVisual Arrow visual to be updated.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// \param[in] _arrowVisual Arrow visual to be updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// \param[in] _axis Axis vector.
/// \param[in] _xyzExpressedIn Frame in which the axis vector is
/// expressed.
/// \param[in] _parentName Name of the joint parent.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// \param[in] _parentName Name of the joint parent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while (this->ChildCount() > 0u)
{
auto visual = std::dynamic_pointer_cast<Visual>(this->ChildByIndex(0));
visual->Destroy();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
visual->Destroy();
if(visual)
{
visual->Destroy();
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 25 to 30
#include "ignition/rendering/base/BaseObject.hh"
#include "ignition/rendering/base/BaseRenderTypes.hh"
#include "ignition/rendering/ArrowVisual.hh"
#include "ignition/rendering/AxisVisual.hh"
#include "ignition/rendering/JointVisual.hh"
#include "ignition/rendering/Scene.hh"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include "ignition/rendering/base/BaseObject.hh"
#include "ignition/rendering/base/BaseRenderTypes.hh"
#include "ignition/rendering/ArrowVisual.hh"
#include "ignition/rendering/AxisVisual.hh"
#include "ignition/rendering/JointVisual.hh"
#include "ignition/rendering/Scene.hh"
#include "ignition/rendering/ArrowVisual.hh"
#include "ignition/rendering/AxisVisual.hh"
#include "ignition/rendering/JointVisual.hh"
#include "ignition/rendering/Scene.hh"
#include "ignition/rendering/base/BaseObject.hh"
#include "ignition/rendering/base/BaseRenderTypes.hh"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


/// \brief Flag to update the parent axis visual.
protected: bool updateParentAxis = false;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 195 to 196
if (this->ParentAxisVisual())
this->ParentAxisVisual()->PreRender();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (this->ParentAxisVisual())
this->ParentAxisVisual()->PreRender();
if (this->ParentAxisVisual())
{
this->ParentAxisVisual()->PreRender();
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const std::string &_name)
{
OgreJointVisualPtr visual(new OgreJointVisual);
bool result = this->InitObject(visual, _id, _name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool result = this->InitObject(visual, _id, _name);
bool result = this->InitObject(visual, _id, _name);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -87,6 +88,7 @@ namespace ignition
typedef shared_ptr<Ogre2GpuRays> Ogre2GpuRaysPtr;
typedef shared_ptr<Ogre2Grid> Ogre2GridPtr;
typedef shared_ptr<Ogre2InertiaVisual> Ogre2InertiaVisualPtr;
typedef shared_ptr<Ogre2JointVisual> Ogre2JointVisualPtr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codecov
Copy link

codecov bot commented Jul 19, 2021

Codecov Report

Merging #366 (b2936e0) into main (afa2270) will increase coverage by 0.43%.
The diff coverage is 82.54%.

❗ Current head b2936e0 differs from pull request most recent head fc6c6e3. Consider uploading reports for the commit fc6c6e3 to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##             main     #366      +/-   ##
==========================================
+ Coverage   58.16%   58.59%   +0.43%     
==========================================
  Files         170      174       +4     
  Lines       16788    17062     +274     
==========================================
+ Hits         9765     9998     +233     
- Misses       7023     7064      +41     
Impacted Files Coverage Δ
include/ignition/rendering/ArrowVisual.hh 100.00% <ø> (ø)
include/ignition/rendering/AxisVisual.hh 0.00% <ø> (-100.00%) ⬇️
include/ignition/rendering/JointVisual.hh 0.00% <0.00%> (ø)
include/ignition/rendering/Node.hh 100.00% <ø> (ø)
include/ignition/rendering/Scene.hh 0.00% <ø> (ø)
include/ignition/rendering/base/BaseScene.hh 0.00% <ø> (ø)
ogre/src/OgreJointVisual.cc 0.00% <0.00%> (ø)
ogre/src/OgreScene.cc 26.66% <0.00%> (-0.37%) ⬇️
ogre2/src/Ogre2JointVisual.cc 50.00% <50.00%> (ø)
include/ignition/rendering/base/BaseNode.hh 81.63% <60.00%> (-0.57%) ⬇️
... and 13 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update afa2270...fc6c6e3. Read the comment docs.

Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
quat.Axis((v.Cross(u)).Normalize(), angle);
_arrowVisual->SetLocalRotation(quat);

if (_xyzExpressedIn == "__model__")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think about creating here a enum, instead of this string ? It looks weird

Copy link
Contributor Author

@atharva-18 atharva-18 Jul 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value of _xyzExpressedIn is __model__ whenever the joint axis vector is expressed in the parent frame. How about a boolean value, for example, useParentFrame that is set to true whenever the joint axis vector is expressed in the parent frame? Using _xyzExpressedIn as a string looks more verbose, however.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iche033 thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using the string _model_ can be tricky. We can have joints connecting two different models and also nested models. Ign-rendering also doesn't have the concept of a 'model' as it's just a scene tree with nodes in hierarchical structure. The current implementation looks like it's relative to its parent so I think a bool useParentFrame fits better.

An alternative option is to take the name or id of a node as an argument. The function then creates the axis relative to that node.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

friendly ping @atharva-18

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using the string _model_ can be tricky. We can have joints connecting two different models and also nested models. Ign-rendering also doesn't have the concept of a 'model' as it's just a scene tree with nodes in hierarchical structure. The current implementation looks like it's relative to its parent so I think a bool useParentFrame fits better.

An alternative option is to take the name or id of a node as an argument. The function then creates the axis relative to that node.

The axis is relative to the parent visual, so using useParentFrame would be a better option (The user would also have to fetch and pass the parent node id every time in the other case).

https://github.com/ignitionrobotics/ign-rendering/blob/4cde82345b3653cd3ee9f1907770daae2859626c/include/ignition/rendering/base/BaseJointVisual.hh#L399-L404

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright sounds good. Let's go with useParentFrame

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in bfbb44b

@chapulina
Copy link
Contributor

Part of gazebosim/gz-sim#106

@atharva-18 atharva-18 mentioned this pull request Aug 9, 2021
8 tasks
Signed-off-by: Atharva Pusalkar <[email protected]>
Copy link
Contributor

@ahcorde ahcorde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some minor fixes

@@ -881,6 +881,35 @@ namespace ignition
public: virtual InertiaVisualPtr CreateInertiaVisual(
unsigned int _id, const std::string &_name) = 0;

/// \brief Create new Joint visual. A unique ID and name will
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// \brief Create new Joint visual. A unique ID and name will
/// \brief Create new joint visual. A unique ID and name will

here and below

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!engine)
{
igndbg << "Engine '" << _renderEngine
<< "' is not supported" << std::endl;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<< "' is not supported" << std::endl;
<< "' is not supported" << std::endl;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahcorde
Copy link
Contributor

ahcorde commented Aug 17, 2021

@iche033 do you mind to review it ? I would love to include this on Fortress

Signed-off-by: Atharva Pusalkar <[email protected]>
@iche033
Copy link
Contributor

iche033 commented Aug 17, 2021

@iche033 do you mind to review it ? I would love to include this on Fortress

yep, I'll get to this soon

Copy link
Contributor

@iche033 iche033 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

works well for me. I have a few minor comments on style and doxygen comments. One suggestion is about the consistency between joint type and visualization, see comment in visualization_demo

template <class T>
void BaseArrowVisual<T>::Destroy()
{
while (this->ChildCount() > 0u)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this go into infinite loop? Do you need to actually remove the child after destroying it?

When I ran the ArrowVisual and JointVisual unit tests, the ChildCount() prints out 0 though.

Copy link
Contributor Author

@atharva-18 atharva-18 Aug 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The child count is decremented every time Destroy() is called on one of its children.
Doing this step is necessary because the arrow visual associated with a joint still remains in the scene after removing the model:
Screenshot from 2021-08-18 11-05-10 Screenshot from 2021-08-18 11-05-23
This is similar to what I faced in the InertiaVisual class, the purple box remained in the scene even after destroying its parent visual (Inertia).

Maybe we can, to be safe, store the references to arrow visual children (shaft, head, and rotation) explicitly in variables, and destroy them whenever ArrowVisual->Destroy() is called?

Currently, arrow shaft, rotation, and head are accessed by index:
https://github.com/ignitionrobotics/ign-rendering/blob/4884de6cc4c0b798d9214101f53b726fa73503fe/include/ignition/rendering/base/BaseArrowVisual.hh#L103-L120

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok sounds good. I think this is fine. Can you add this snippet below to the end of ArrowVisual_TEST.cc so we have some coverage for this bit of code?

  // test destroy
  ArrowVisualPtr visual2 = scene->CreateArrowVisual();
  ASSERT_NE(nullptr, visual2);
  visual2->Destroy();
  EXPECT_EQ(0u, visual2->ChildCount());

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in fc6c6e3


// Documentation inherited.
public: virtual void SetAxis(const ignition::math::Vector3d &_axis,
const bool _useParentFrame) override;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we started omitting const for primitive types, so just bool _useParentFrame

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -48,6 +48,8 @@ namespace ignition

public: virtual math::Pose3d LocalPose() const override;

public: virtual math::Pose3d InitialLocalPose() const override;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add // Documentation inherited here?

Copy link
Contributor Author

@atharva-18 atharva-18 Aug 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -196,6 +198,11 @@ namespace ignition

protected: math::Vector3d origin;

protected: bool initialLocalPoseSet = false;

protected: ignition::math::Pose3d initialLocalPose =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add doxygen comments for these new variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -277,6 +277,12 @@ namespace ignition
protected: virtual InertiaVisualPtr CreateInertiaVisualImpl(
unsigned int _id, const std::string &_name) = 0;

/// \brief Implementation for creating Joint visual.
/// \param[in] _id Unique id
/// \param[in] _name Name of Joint visual
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add \return

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jointParentBox->SetLocalRotation(0, 0, 0);
jointParentBox->SetMaterial(blue);
jointParentBox->Material()->SetTransparency(0.5);
jointParentBox->Material()->SetDepthWriteEnabled(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  jointParentBox->Material()->SetTransparency(0.5);
  jointParentBox->Material()->SetDepthWriteEnabled(false);

do you still need to these 2 calls? The blue material should have these set.

Alternatively, set to a different color material so it's easier to distinguish between parent and child box

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed material to gray in 3d31542

/// \return True if parent axis was updated else false.
public: virtual bool UpdateParentAxis(
const ignition::math::Vector3d &_axis,
const bool _useParentFrame = false) = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can omit const for primitive types. Same goes for other functions in this class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JointVisualPtr jointVisual = _scene->CreateJointVisual();
jointChildBox->AddChild(jointVisual);
jointVisual->SetType(JointVisualType::JVT_REVOLUTE);
ignition::math::Vector3d axis2(1.0, 0.0, 0.0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set to a non-unit axis to show what the joint visual would look like? ,e.g. axis2(1.0, 1.0, 1.0)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jointParentBox->AddGeometry(_scene->CreateBox());
jointParentBox->SetOrigin(0.0, 0.0, 0.0);
jointParentBox->SetLocalPosition(2.0, 0.5, 0.0);
jointParentBox->SetLocalRotation(0, 0, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use a different rotation from child to show what the parent axis looks like with rotation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// create joint visual
JointVisualPtr jointVisual = _scene->CreateJointVisual();
jointChildBox->AddChild(jointVisual);
jointVisual->SetType(JointVisualType::JVT_REVOLUTE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a little confused at first to see 2 joint visuals while the type is JVT_REVOLUTE. I would expect this to be JVT_REVOLUTE2 or JVT_UNIVERSAL. Maybe only create the parent axes or make it visible if joint type is revolute2 / universal?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

714d523 should fix it

Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
Signed-off-by: Atharva Pusalkar <[email protected]>
@ahcorde ahcorde merged commit 3cbd121 into gazebosim:main Aug 19, 2021
@osrf-triage
Copy link

This pull request has been mentioned on Gazebo Community. There might be relevant details there:

https://community.gazebosim.org/t/google-summer-of-code-2021-new-gui-widgets-in-ignition-gazebo/1081/1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏯 fortress Ignition Fortress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants