PlatformInertia.cpp
Go to the documentation of this file.
1/**
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @author Fabian Reister ( fabian dot reister at kit dot edu )
17 * @date 2026
18 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19 * GNU General Public License
20 */
21
22#include "PlatformInertia.h"
23
24#include <filesystem>
25#include <stdexcept>
26
31
32#if NAVIGATION_SIMULATION_SIMOX_CONTROL
33
34#include <VirtualRobot/Robot.h>
35#include <VirtualRobot/RobotNodeSet.h>
36#include <VirtualRobot/XML/RobotIO.h>
37
38#include <simox/control/dynamics/RBDLModel.h>
39#include <simox/control/impl/simox/dynamics/VirtualRobotRBDLModel.h>
40
41#endif
42
44{
45
46#if NAVIGATION_SIMULATION_SIMOX_CONTROL
47
48 PlatformInertia::PlatformInertia(const Parameters& params) : params_(params)
49 {
50 const std::string filename =
51 armarx::PackagePath(params_.robotPackage, params_.robotFile).toSystemPath();
52
53 ARMARX_CHECK(std::filesystem::exists(filename))
54 << "Robot model " << QUOTED(filename) << " does not exist.";
55
56 // eStructure skips visualization and collision meshes; <Physics> is still parsed, which
57 // is all the dynamics model needs.
58 robot_ = VirtualRobot::RobotIO::loadRobot(filename, VirtualRobot::RobotIO::eStructure);
59 ARMARX_CHECK_NOT_NULL(robot_) << "Failed to load " << QUOTED(filename);
60
61 ARMARX_CHECK(robot_->hasConfiguration(params_.configuration))
62 << "Robot has no configuration " << QUOTED(params_.configuration) << ".";
63
64 // Must happen before the RBDL model is built: simox-control lumps the bodies using the
65 // transforms as they are at construction time.
66 ARMARX_CHECK(robot_->setToConfiguration(params_.configuration));
67
68 const VirtualRobot::RobotNodeSetPtr rns = robot_->getRobotNodeSet(params_.nodeSet);
69 ARMARX_CHECK_NOT_NULL(rns) << "Robot has no node set " << QUOTED(params_.nodeSet) << ".";
70
71 // rnsBodies = nullptr lumps every mass below the platform onto the platform bodies,
72 // which is exactly the whole-robot inertia we are after.
73 model_ = std::make_unique<simox::control::simox::dynamics::VirtualRobotRBDLModel>(rns);
74
75 ARMARX_CHECK_EQUAL(model_->getnDoF(), 3)
76 << "Expected a 3-DoF reduced platform model from node set "
77 << QUOTED(params_.nodeSet) << " but got " << model_->getnDoF()
78 << " DoF. The [x, y, yaw] block extraction below assumes indices 0, 1, 2.";
79
80 // The translation/rotation cross-terms come from the centre of mass being offset from
81 // the yaw axis. On ARMAR-7 they are larger than the yaw inertia itself, so they must
82 // not be dropped when sizing acceleration limits.
83 const Eigen::Matrix3d M = massMatrix(Eigen::Vector3d::Zero());
84
85 ARMARX_IMPORTANT << "Platform dynamics from " << QUOTED(filename) << " in configuration "
86 << QUOTED(params_.configuration) << ": mass " << M(0, 0)
87 << " kg, yaw inertia " << M(2, 2) << " kg m^2.\n"
88 << "Mass matrix [x, y, yaw] (kg, kg, kg m^2):\n"
89 << M;
90 }
91
93
94 Eigen::Matrix3d
95 PlatformInertia::massMatrix(const Eigen::Vector3d& q)
96 {
97 // q is already [m, m, rad]; simox-control builds the RBDL model in metres but never
98 // scales q itself, so the caller owes us metres for the prismatic DoFs.
99 return model_->getInertiaMatrix(q);
100 }
101
102 Eigen::Vector3d
103 PlatformInertia::bias(const Eigen::Vector3d& q, const Eigen::Vector3d& qdot)
104 {
105 return model_->getInverseDynamics(q, qdot, Eigen::Vector3d::Zero());
106 }
107
108 double
110 {
111 return massMatrix(Eigen::Vector3d::Zero())(0, 0);
112 }
113
114 double
116 {
117 return massMatrix(Eigen::Vector3d::Zero())(2, 2);
118 }
119
120#else
121
123 {
124 throw std::runtime_error(
125 "The omni-wheel torque model needs the platform inertia, which requires "
126 "SimoxControl. This build of armarx_navigation was configured without it. Use a "
127 "different `model` in PlatformDynamics.json, or rebuild with SimoxControl available.");
128 }
129
131
132 Eigen::Matrix3d
133 PlatformInertia::massMatrix(const Eigen::Vector3d&)
134 {
135 return Eigen::Matrix3d::Identity();
136 }
137
138 Eigen::Vector3d
139 PlatformInertia::bias(const Eigen::Vector3d&, const Eigen::Vector3d&)
140 {
141 return Eigen::Vector3d::Zero();
142 }
143
144 double
146 {
147 return 0.0;
148 }
149
150 double
152 {
153 return 0.0;
154 }
155
156#endif
157
158} // namespace armarx::navigation::simulation
#define QUOTED(x)
static std::filesystem::path toSystemPath(const data::PackagePath &pp)
double yawInertia()
Moment of inertia about the platform's yaw axis [kg m^2], at zero yaw.
Eigen::Matrix3d massMatrix(const Eigen::Vector3d &q)
Joint-space mass matrix at platform pose q.
double totalMass()
Total mass of everything lumped onto the platform [kg], i.e. massMatrix(0)(0, 0).
Eigen::Vector3d bias(const Eigen::Vector3d &q, const Eigen::Vector3d &qdot)
Coriolis, centrifugal and gravity terms at the platform DoFs.
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:188
#define q
This file is part of ArmarX.