MoveRelativePlanar.cpp
Go to the documentation of this file.
2
3#include <optional>
4#include <sstream>
5#include <string>
6
7#include <SimoxUtility/math/convert/deg_to_rad.h>
8#include <VirtualRobot/VirtualRobot.h>
9
14
16#include <RobotAPI/libraries/aron/common/aron/framed.aron.generated.h>
19
21#include <armarx/navigation/skills/aron/MoveRelativePlanar.aron.generated.h>
22#include <armarx/navigation/skills/aron/NavigatingSkillParams.aron.generated.h>
24
26{
27
28 armarx::skills::SkillDescription
30 {
31 ParamType defaultParams;
32 defaultParams.translationCartesian = std::nullopt;
33 defaultParams.translationPolar = std::nullopt;
34 defaultParams.rotationRadians = std::nullopt;
35 defaultParams.rotationDegrees = std::nullopt;
36 defaultParams.navigatingSkillParams = NavigatingSkillHelper::DefaultSkillDescription();
37 defaultParams.navigatingSkillParams.globalPlanningAlgorithm =
38 arondto::GlobalPlanningAlgorithm::Point2Point;
39 defaultParams.navigatingSkillParams.p2pCheckCollisionsAlongTrajectory = false;
40
41 static const std::string nl = "\n\n";
42
43 std::stringstream desc;
44 desc << "**Move the robot relatively to its current pose in the horizontal plane.**";
45
46 desc << nl
47 << "The parameters `translationCartesian` and `translationPolar` specify the "
48 "translation of the robot. (If both are given, `translationCartesian` takes "
49 "precedence over `translationPolar`.)";
50
51 desc << nl
52 << "`translationCartesian` specifies the relative translation in Cartesian"
53 " coordinates (x, y). The corresponding coordinate system is specified by its "
54 "`frameID`. If `frameID` is not given, the robot's root coordinate system is used."
55 "To define a translation in the global frame, set `frame` to `Global` (and leave "
56 "`agent` empty).";
57
58 desc << nl
59 << "`translationPolar` specifies the relative translation in polar coordinates"
60 " (direction, distance), where"
61 << nl << "- `direction = 0` moves the robot forward," << nl
62 << "- `direction > 0` moves the robot to the left," << nl
63 << "- `direction < 0` moves the robot to the right." << nl
64 << " (Generally, `forward` is defined as the +y axis of the robot root frame.)";
65
66 desc << nl
67 << "`rotationRadians` and `rotationDegrees` specify the rotation around the +z axis"
68 " (up). "
69 << nl
70 << "(If both are given, `rotationRadians` takes precedence over `rotationDegrees`.)"
71 << nl << "- `directionDegrees = 0` does not turn the robot," << nl
72 << "- `directionDegrees > 0` turns the robot to the left," << nl
73 << "- `directionDegrees < 0` turns the robot to the right.";
74
76 .skillId = {.skillName = constants::skill_names::MoveRelativePlanar},
77 .description = desc.str(),
78 .rootProfileDefaults = defaultParams.toAron(),
80 .parametersType = ParamType::ToAronType(),
81 };
82 }
83
86 const Properties& properties,
87 const Services& srv) :
88 Base(baseProperties, baseSrv, DefaultSkillDescription()),
89 properties{properties},
90 services{srv}
91 {
92 }
93
94 namespace
95 {
96
97 Eigen::Vector3f
98 makeTranslation(const arondto::FramedCartesian2D& cartesian,
100 const std::string& defaultRobotName)
101 {
102 Eigen::Vector3f translation;
103 translation << cartesian.translationCartesian.cast<float>(), 0;
104
105 // Target translation must be given in root frame of robot.
106 if (cartesian.frameID.has_value())
107 {
108 armarx::arondto::FrameID frameID = cartesian.frameID.value();
109
110 if (frameID.agent.empty())
111 {
112 // If frame == armarx::GlobalFrame, the agent is ignored, so we can set it anyway.
113 frameID.agent = defaultRobotName;
114 }
115
116 VirtualRobot::RobotPtr robot = robotReader.getRobot(frameID.agent);
118 << "Robot " << QUOTED(frameID.agent) << " not found in robot reader";
119
121 << "Failed to synchronize robot " << QUOTED(frameID.agent);
122
123 if (frameID.frame.empty())
124 {
125 frameID.frame = robot->getRootNode()->getName();
126 }
127
128 armarx::FramedDirection dir(translation, frameID.frame, frameID.agent);
129
130 return dir.toRootFrame(robot)->toEigen();
131 }
132 else
133 {
134 // If not given, we fall back to the robot root frame => no transformation necessary.
135 return translation;
136 }
137 }
138
139 Eigen::Vector3f
140 makeTranslation(const arondto::Polar& polar,
141 const Eigen::Vector3f forward,
142 const Eigen::Vector3f up)
143 {
144 const Eigen::AngleAxisf rotation(simox::math::deg_to_rad(polar.directionDegrees), up);
145 const Eigen::Vector3f translation = polar.distanceMillimeters * (rotation * forward);
146
147 return translation;
148 }
149
150 Eigen::AngleAxisf
151 makeRotation(float rotationRadians, const Eigen::Vector3f up)
152 {
153 return Eigen::AngleAxisf(rotationRadians, up);
154 }
155 } // namespace
156
157 Eigen::Isometry3f
158 MoveRelativePlanar::relativeTarget(const Base::SpecializedMainInput& in)
159 {
160 // Note: In theory, it depends on the robot.
161 static const Eigen::Vector3f forward = Eigen::Vector3f::UnitY();
162 static const Eigen::Vector3f up = Eigen::Vector3f::UnitZ();
163
164 const ParamType& parameters = in.parameters;
165
166 Eigen::Isometry3f relativeTarget = Eigen::Isometry3f::Identity();
167
168 // Translation.
169 if (parameters.translationCartesian.has_value())
170 {
171 relativeTarget.translation() = makeTranslation(parameters.translationCartesian.value(),
172 services.robotReader,
173 properties.robotName);
174 }
175 else if (parameters.translationPolar.has_value())
176 {
177 relativeTarget.translation() =
178 makeTranslation(parameters.translationPolar.value(), forward, up);
179 }
180
181 // Rotation.
182 std::optional<float> rotationRadians = parameters.rotationRadians;
183 if (not rotationRadians.has_value() and parameters.rotationDegrees.has_value())
184 {
185 rotationRadians = simox::math::deg_to_rad(parameters.rotationDegrees.value());
186 }
187 if (rotationRadians.has_value())
188 {
189 relativeTarget.linear() =
190 relativeTarget.linear() * makeRotation(rotationRadians.value(), up);
191 }
192
193 return relativeTarget;
194 }
195
196} // namespace armarx::navigation::skills
#define QUOTED(x)
static DateTime Now()
Current time on the virtual clock.
Definition Clock.cpp:93
FramedDirection is a 3 dimensional direction vector with a reference frame.
Definition FramedPose.h:87
VirtualRobot::RobotPtr getRobot(const std::string &name, const armem::Time &timestamp=armem::Time::Invalid(), const VirtualRobot::RobotIO::RobotDescription &loadMode=VirtualRobot::RobotIO::RobotDescription::eStructure)
bool synchronizeRobotPose(VirtualRobot::Robot &robot, const armem::Time &timestamp) const
Synchronize only the platform pose of a virtual robot, according to the robot state memory for a cert...
static Duration Minutes(std::int64_t minutes)
Constructs a duration in minutes.
Definition Duration.cpp:96
MoveRelativePlanar(const NavigatingSkillHelper::Properties &baseProperties, const NavigatingSkillHelper::Services &baseSrv, const Properties &properties, const Services &srv)
static armarx::skills::SkillDescription DefaultSkillDescription()
NavigateRelativeSkill< arondto::MoveRelativePlanarParams > Base
static arondto::NavigatingSkillParams DefaultSkillDescription()
armarx::aron::data::DictPtr parameters
Definition Skill.h:369
#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...
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19