Skip to content
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

Set link velocity from set_model_state plugin #2440

Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b062cc1
modified velocity reset components
yaswanth1701 Jun 6, 2024
bb213b5
updated physic plugin to set initial link velocities
yaswanth1701 Jun 6, 2024
53e2b33
updated set_model_state plugin for creating link velocity resert comp…
yaswanth1701 Jun 6, 2024
d46c143
updated model state sdf to test link velocity reset component
yaswanth1701 Jun 6, 2024
5b73d20
added root link check for link
yaswanth1701 Jun 8, 2024
72d75f9
pre commit hooks
yaswanth1701 Jun 8, 2024
7baa3b8
fixed line length
yaswanth1701 Jun 8, 2024
116a728
minor changes
yaswanth1701 Jun 8, 2024
327eaa3
added inertia to box in set_model_state sdf
yaswanth1701 Jun 8, 2024
9f3555d
minor changes
yaswanth1701 Jun 9, 2024
1a390c0
minor changes
yaswanth1701 Jun 9, 2024
8e730cc
minor changes
yaswanth1701 Jun 9, 2024
3db0e98
resolved formatting comments
yaswanth1701 Jun 11, 2024
b9e559b
resolved linting error
yaswanth1701 Jun 11, 2024
b8deab3
added flag to account for reset components only once
yaswanth1701 Jun 17, 2024
778b2fb
added zero gravity to sdf
yaswanth1701 Jun 17, 2024
0066023
fixed linting errors
yaswanth1701 Jun 19, 2024
37b026c
removed reset components in updatesim physics.cc
yaswanth1701 Jun 22, 2024
4cebd44
fixes linting errors
yaswanth1701 Jun 22, 2024
44554a2
added degree option for angular velocity in set_model_state system
yaswanth1701 Jun 30, 2024
b335da9
resolved linting errors
yaswanth1701 Jun 30, 2024
51f04cc
added some comments to sdf files
yaswanth1701 Jun 30, 2024
3dd6404
changes to degree to radian conversion
yaswanth1701 Jul 11, 2024
cdee544
fixed linting errors
yaswanth1701 Jul 11, 2024
c9d6690
fixed linting errors
yaswanth1701 Jul 11, 2024
6cf3856
minor changes
yaswanth1701 Aug 8, 2024
9de189c
Merge remote-tracking branch 'origin/scpeters/set_model_state_prototy…
scpeters Aug 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions examples/worlds/set_model_state.sdf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
-->
<sdf version="1.6">
<world name="set_model_state">
<gravity>0 0 0</gravity>
<plugin
filename="gz-sim-physics-system"
name="gz::sim::systems::Physics">
Expand Down Expand Up @@ -248,5 +249,54 @@
</model_state>
</plugin>
</model>

<model name="model_state_example_link_velocity">
<pose>2 0 1 0 0 0</pose>
<link name="box_link">
<pose>0.0 0.0 0.0 0 0 0</pose>
<inertial>
<inertia>
<ixx>5</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>5</iyy>
<iyz>0</iyz>
<izz>5</izz>
</inertia>
<mass>120.0</mass>
Copy link
Member

Choose a reason for hiding this comment

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

I updated #2359 to use auto-inertials in the example world in 7cab1bb

I think we should use a box with 3 different dimensions rather than a cube in order to visualize the Dzhanibekov effect. I think the dimensions from the boxes benchmark test (0.1, 0.4, 0.9) and initial angular velocity with largest component in Y (0.1, 5.0, 0.1) would work well. With the updated dimensions, we could use auto-inertials as well.

</inertial>
<visual name="box_visual">
<pose>0.0 0.0 0.0 0 0 0</pose>
<geometry>
<box>
<size>0.5 0.5 0.5</size>
</box>
</geometry>
<material>
<ambient>1.0 0.0 0.0 1</ambient>
<diffuse>1.0 0.0 0.0 1</diffuse>
<specular>1.0 0.0 0.0 1</specular>
</material>
</visual>
<collision name="box_collision">
<pose>0.0 0.0 0.0 0 0 0</pose>
<geometry>
<box>
<size>0.5 0.5 0.5</size>
</box>
</geometry>
</collision>
</link>
<plugin
filename="gz-sim-set-model-state-system"
name="gz::sim::systems::SetModelState">
<model_state>
<link_state name="box_link">
<linear_velocity>0.1 -0.1 0.1</linear_velocity>
<angular_velocity>1 2 1</angular_velocity>
Copy link
Member

Choose a reason for hiding this comment

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

I recommend adding a degrees boolean attribute to //link_state/angular_velocity to match the behavior of the //joint_state/position/@degrees and //joint_state/velocity/@degrees attributes. Then it would be nice to have pair of example boxes with angular velocity expressed in both deg/s and rad/s

Copy link
Contributor Author

@yaswanth1701 yaswanth1701 Jun 29, 2024

Choose a reason for hiding this comment

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

got it, I will make the changes

</link_state>
</model_state>
</plugin>
</model>
</world>
</sdf>
47 changes: 47 additions & 0 deletions include/gz/sim/components/WorldAngularVelocityReset.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (C) 2024 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GZ_SIM_COMPONENTS_WORLDANGULARVELOCITYRESET_HH_
#define GZ_SIM_COMPONENTS_WORLDANGULARELOCITYRESET_HH_

#include <gz/math/Vector3.hh>
#include <gz/sim/components/Component.hh>
#include <gz/sim/components/Factory.hh>
#include <gz/sim/components/Serialization.hh>
#include <gz/sim/config.hh>

namespace gz
{
namespace sim
{
// Inline bracket to help doxygen filtering.
inline namespace GZ_SIM_VERSION_NAMESPACE {
namespace components
{
/// \brief Link angular velocity in world frame in SI units (rad/s).
///
/// The component wraps a std::vector of size equal to the degrees of freedom
/// of the joint.
using WorldAngularVelocityReset = Component<math::Vector3d,
class WorldAngularVelocityResetTag>;
GZ_SIM_REGISTER_COMPONENT(
"gz_sim_components.WorldAngularVelocityReset", WorldAngularVelocityReset)
}
}
}
}

#endif
47 changes: 47 additions & 0 deletions include/gz/sim/components/WorldLinearVelocityReset.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (C) 2024 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GZ_SIM_COMPONENTS_WORLDLINEARVELOCITYRESET_HH_
#define GZ_SIM_COMPONENTS_WORLDLINEARVELOCITYRESET_HH_

#include <gz/math/Vector3.hh>
#include <gz/sim/components/Component.hh>
#include <gz/sim/components/Factory.hh>
#include <gz/sim/components/Serialization.hh>
#include <gz/sim/config.hh>

namespace gz
{
namespace sim
{
// Inline bracket to help doxygen filtering.
inline namespace GZ_SIM_VERSION_NAMESPACE {
namespace components
{
/// \brief Link linear velocity in world frame in SI units (m/s).
///
/// The component wraps a std::vector of size equal to the degrees of freedom
/// of the joint.
using WorldLinearVelocityReset = Component<math::Vector3d ,
class WorldLinearVelocityResetTag>;
GZ_SIM_REGISTER_COMPONENT(
"gz_sim_components.WorldLinearVelocityReset", WorldLinearVelocityReset)
}
}
}
}

#endif
135 changes: 135 additions & 0 deletions src/systems/physics/Physics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@
#include "gz/sim/components/LinearAcceleration.hh"
#include "gz/sim/components/LinearVelocity.hh"
#include "gz/sim/components/LinearVelocityCmd.hh"
#include "gz/sim/components/WorldLinearVelocityReset.hh"
#include "gz/sim/components/WorldAngularVelocityReset.hh"
#include "gz/sim/components/Link.hh"
#include "gz/sim/components/Model.hh"
#include "gz/sim/components/Name.hh"
Expand Down Expand Up @@ -372,6 +374,14 @@ class gz::sim::systems::PhysicsPrivate
/// \brief Pointer to the underlying gz-physics Engine entity.
public: EnginePtrType engine = nullptr;

/// \brief Flag indicating wheather link linear velocity component is
/// already set.
public: bool linearVelocityResetFlag = false;

/// \brief Flag indicating wheather link angular velocity compi340onent
/// is already set.
public: bool angularVelocityResetFlag = false;

/// \brief Vector3d equality comparison function.
public: std::function<bool(const math::Vector3d &, const math::Vector3d &)>
vec3Eql { [](const math::Vector3d &_a, const math::Vector3d &_b)
Expand Down Expand Up @@ -2643,6 +2653,131 @@ void PhysicsPrivate::UpdatePhysics(EntityComponentManager &_ecm)
return true;
});

// Set initial link linear velocity
_ecm.Each<components::Link, components::WorldLinearVelocityReset>(
[&](const Entity &_entity, const components::Link *,
const components::WorldLinearVelocityReset *_worldlinearvelocityreset)
{
if (!this->entityLinkMap.HasEntity(_entity))
{
gzwarn << "Failed to find link [" << _entity
<< "]." << std::endl;
return true;
}

auto linkPtrPhys = this->entityLinkMap.Get(_entity);
if (nullptr == linkPtrPhys)
return true;

auto freeGroup = linkPtrPhys->FindFreeGroup();
if (!freeGroup)
return true;

auto rootLinkPtr = freeGroup->RootLink();
if(rootLinkPtr != linkPtrPhys)
{
gzwarn << "Attempting to set linear velocity for link [ " << _entity
<< " ] which is not root link of the FreeGroup."
<< "Velocity won't be set." << std::endl;

return true;
}

this->entityFreeGroupMap.AddEntity(_entity, freeGroup);

auto worldLinearVelFeature =
this->entityFreeGroupMap
.EntityCast<WorldVelocityCommandFeatureList>(_entity);
if (!worldLinearVelFeature)
{
static bool informed{false};
if (!informed)
{
gzdbg << "Attempting to set link linear velocity, but the "
<< "physics engine doesn't support velocity commands. "
<< "Velocity won't be set."
<< std::endl;
informed = true;
}
return true;
}

// Linear velocity in world frame
math::Vector3d worldLinearVel = _worldlinearvelocityreset->Data();

if(!linearVelocityResetFlag)
{
worldLinearVelFeature->SetWorldLinearVelocity(
math::eigen3::convert(worldLinearVel));
this->linearVelocityResetFlag = true;
}

return true;
});

// Set initial link angular velocity
_ecm.Each<components::Link, components::WorldAngularVelocityReset>(
[&](const Entity &_entity, const components::Link *,
const components::WorldAngularVelocityReset
*_worldangularvelocityreset)
{
if (!this->entityLinkMap.HasEntity(_entity))
{
gzwarn << "Failed to find link [" << _entity
<< "]." << std::endl;
return true;
}

auto linkPtrPhys = this->entityLinkMap.Get(_entity);
if (nullptr == linkPtrPhys)
return true;

auto freeGroup = linkPtrPhys->FindFreeGroup();
if (!freeGroup)
return true;

auto rootLinkPtr = freeGroup->RootLink();
if(rootLinkPtr != linkPtrPhys)
{
gzwarn << "Attempting to set angular velocity for link [ " << _entity
<< " ] which is not root link of the FreeGroup."
<< "Velocity won't be set." << std::endl;

return true;
}

this->entityFreeGroupMap.AddEntity(_entity, freeGroup);

auto worldAngularVelFeature =
this->entityFreeGroupMap
.EntityCast<WorldVelocityCommandFeatureList>(_entity);

if (!worldAngularVelFeature)
{
static bool informed{false};
if (!informed)
{
gzdbg << "Attempting to set link angular velocity, but the "
<< "physics engine doesn't support velocity commands. "
<< "Velocity won't be set."
<< std::endl;
informed = true;
}
return true;
}
// Angular velocity in world frame
math::Vector3d worldAngularVel = _worldangularvelocityreset->Data();

if(!angularVelocityResetFlag)
{
worldAngularVelFeature->SetWorldAngularVelocity(
math::eigen3::convert(worldAngularVel));
this->angularVelocityResetFlag = true;
}
Copy link
Member

Choose a reason for hiding this comment

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

I see that this is your logic for ensuring that the VelocityReset components are only acted on a single time, but I recommend following the method used for the JointVelocityReset component, which is to delete the component after it has been acted on:

  • std::vector<Entity> entitiesVelocityReset;
    _ecm.Each<components::JointVelocityReset>(
    [&](const Entity &_entity, components::JointVelocityReset *) -> bool
    {
    entitiesVelocityReset.push_back(_entity);
    return true;
    });
    for (const auto entity : entitiesVelocityReset)
    {
    _ecm.RemoveComponent<components::JointVelocityReset>(entity);
    }


return true;
});


// Populate bounding box info
// Only compute bounding box if component exists to avoid unnecessary
Expand Down
61 changes: 61 additions & 0 deletions src/systems/set_model_state/SetModelState.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@

#include <gz/common/Profiler.hh>
#include <gz/math/Angle.hh>
#include <gz/math/Vector3.hh>
#include <gz/plugin/Register.hh>

#include "gz/sim/components/JointAxis.hh"
#include "gz/sim/components/JointPositionReset.hh"
#include "gz/sim/components/JointVelocityReset.hh"
#include "gz/sim/components/WorldLinearVelocityReset.hh"
#include "gz/sim/components/WorldAngularVelocityReset.hh"
#include "gz/sim/Model.hh"
#include "gz/sim/Util.hh"

Expand Down Expand Up @@ -222,6 +225,64 @@ void SetModelState::Configure(const Entity &_entity,
jointVelocity);
}
}
for (auto linkStateElem = modelStateElem->FindElement("link_state");
linkStateElem != nullptr;
linkStateElem = linkStateElem->GetNextElement("link_state"))
{

std::pair<std::string, bool> namePair =
linkStateElem->Get<std::string>("name", "");
if (!namePair.second)
{
gzerr << "No name specified for link_state, skipping.\n";
continue;
}
const auto &linkName = namePair.first;

Entity linkEntity = this->dataPtr->model.LinkByName(_ecm, linkName);
if (linkEntity == kNullEntity)
{
gzerr << "Unable to find link with name [" << linkName << "] "
<< "in model with name [" << modelName << "], skipping.\n";
continue;
}

// Default velocity is initialsed as zero vector.
math::Vector3d defaultVelocity;
math::Vector3d linearVelocity;
math::Vector3d angularVelocity;

auto linearVelocityElem = linkStateElem->FindElement("linear_velocity");

if(linearVelocityElem)
{
std::pair<math::Vector3d, bool> vectorPair =
linearVelocityElem->Get<math::Vector3d>("", defaultVelocity);
if (vectorPair.second)
{
linearVelocity = vectorPair.first;
_ecm.SetComponentData<components::WorldLinearVelocityReset>(
linkEntity,
linearVelocity);
}
}

auto angularVelocityElem =
linkStateElem->FindElement("angular_velocity");

if(angularVelocityElem){
std::pair<math::Vector3d, bool> vectorPair =
angularVelocityElem->Get<math::Vector3d>("", defaultVelocity);
if(vectorPair.second)
{
angularVelocity = vectorPair.first;
_ecm.SetComponentData<components::WorldAngularVelocityReset>(
linkEntity,
angularVelocity);

}
}
}
}

//////////////////////////////////////////////////
Expand Down
Loading