Skip to content

Commit e98765e

Browse files
committed
waypoint and waypoint mode from yaml
1 parent f3958dd commit e98765e

2 files changed

Lines changed: 80 additions & 18 deletions

File tree

vortex_utils/include/vortex/utils/waypoint_utils.hpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ struct LandmarkConvergenceGoal {
3131
double dead_reckoning_threshold{0.5};
3232
};
3333

34+
/**
35+
* @brief Convert a string to a WaypointMode enum value.
36+
*
37+
* Accepts both upper-case ("FULL_POSE") and lower-case ("full_pose") variants.
38+
*
39+
* @param str The string representation of the mode.
40+
* @return The corresponding WaypointMode.
41+
* @throws std::runtime_error if the string does not match any known mode.
42+
*/
43+
WaypointMode string_to_waypoint_mode(const std::string& str);
44+
3445
/**
3546
* @brief Compute the waypoint goal by applying the mode logic to the incoming
3647
* waypoint.
@@ -106,15 +117,10 @@ Pose load_pose_from_yaml(const std::string& file_path,
106117
* Expected YAML format:
107118
* @code
108119
* waypoint_name:
109-
* position:
110-
* x: 1.0
111-
* y: 0.0
112-
* z: -0.5
113-
* orientation:
114-
* roll: 0.0
115-
* pitch: 0.0
116-
* yaw: 3.14159
117-
* mode: 0 # WaypointMode as integer (e.g. 0 for FULL_POSE)
120+
* mode: only_position # WaypointMode as string or integer (e.g. 1 /
121+
* "only_position") position: # Required for FULL_POSE,
122+
* ONLY_POSITION, FORWARD_HEADING x: 1.0 y: 0.0 z: -0.5 orientation: #
123+
* Required for FULL_POSE, ONLY_ORIENTATION roll: 0.0 pitch: 0.0 yaw: 3.14159
118124
* convergence_threshold: 0.1 # Optional, default is 0.1
119125
* @endcode
120126
*
@@ -136,15 +142,15 @@ WaypointGoal load_waypoint_goal_from_yaml(const std::string& file_path,
136142
* Expected YAML format:
137143
* @code
138144
* landmark_goal_name:
139-
* position:
145+
* mode: full_pose # WaypointMode as string or integer (e.g. 0 / "full_pose")
146+
* position: # Required for FULL_POSE, ONLY_POSITION, FORWARD_HEADING
140147
* x: 0.0
141148
* y: 0.0
142149
* z: -0.5
143-
* orientation:
150+
* orientation: # Required for FULL_POSE, ONLY_ORIENTATION
144151
* roll: 0.0
145152
* pitch: 0.0
146153
* yaw: 0.0
147-
* mode: 0 # WaypointMode as integer (e.g. 0 for FULL_POSE)
148154
* convergence_threshold: 0.1 # Optional, default is 0.1
149155
* dead_reckoning_threshold: 0.5 # Optional, default is 0.5
150156
* @endcode

vortex_utils/src/waypoint_utils.cpp

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,64 @@
66

77
namespace vortex::utils::waypoints {
88

9+
WaypointMode string_to_waypoint_mode(const std::string& str) {
10+
if (str == "FULL_POSE" || str == "full_pose")
11+
return WaypointMode::FULL_POSE;
12+
if (str == "ONLY_POSITION" || str == "only_position")
13+
return WaypointMode::ONLY_POSITION;
14+
if (str == "FORWARD_HEADING" || str == "forward_heading")
15+
return WaypointMode::FORWARD_HEADING;
16+
if (str == "ONLY_ORIENTATION" || str == "only_orientation")
17+
return WaypointMode::ONLY_ORIENTATION;
18+
throw std::runtime_error("Unknown WaypointMode string: '" + str + "'");
19+
}
20+
21+
namespace {
22+
23+
WaypointMode load_mode(const YAML::Node& node) {
24+
const auto& m = node["mode"];
25+
if (!m) {
26+
throw std::runtime_error("Missing required field 'mode'");
27+
}
28+
try {
29+
return static_cast<WaypointMode>(m.as<uint8_t>());
30+
} catch (const YAML::BadConversion&) {
31+
return string_to_waypoint_mode(m.as<std::string>());
32+
}
33+
}
34+
35+
Pose load_pose_for_mode(const YAML::Node& node, WaypointMode mode) {
36+
Pose pose; // defaults: x=y=z=0, qw=1, qx=qy=qz=0
37+
38+
const bool needs_position = (mode == WaypointMode::FULL_POSE ||
39+
mode == WaypointMode::ONLY_POSITION ||
40+
mode == WaypointMode::FORWARD_HEADING);
41+
const bool needs_orientation = (mode == WaypointMode::FULL_POSE ||
42+
mode == WaypointMode::ONLY_ORIENTATION);
43+
44+
if (needs_position) {
45+
pose.x = node["position"]["x"].as<double>();
46+
pose.y = node["position"]["y"].as<double>();
47+
pose.z = node["position"]["z"].as<double>();
48+
}
49+
50+
if (needs_orientation) {
51+
const double roll = node["orientation"]["roll"].as<double>();
52+
const double pitch = node["orientation"]["pitch"].as<double>();
53+
const double yaw = node["orientation"]["yaw"].as<double>();
54+
const Eigen::Quaterniond q =
55+
vortex::utils::math::euler_to_quat(roll, pitch, yaw);
56+
pose.qw = q.w();
57+
pose.qx = q.x();
58+
pose.qy = q.y();
59+
pose.qz = q.z();
60+
}
61+
62+
return pose;
63+
}
64+
65+
} // namespace
66+
967
Pose compute_waypoint_goal(const Pose& incoming_waypoint,
1068
WaypointMode mode,
1169
const Pose& current_state) {
@@ -118,9 +176,8 @@ WaypointGoal load_waypoint_goal_from_yaml(const std::string& file_path,
118176

119177
const auto& wp = root[identifier];
120178

121-
Pose pose = load_pose_from_yaml(file_path, identifier);
122-
123-
const auto mode = static_cast<WaypointMode>(wp["mode"].as<uint8_t>());
179+
const auto mode = load_mode(wp);
180+
const Pose pose = load_pose_for_mode(wp, mode);
124181

125182
double convergence_threshold = 0.1;
126183
if (wp["convergence_threshold"]) {
@@ -144,9 +201,8 @@ LandmarkConvergenceGoal load_landmark_goal_from_yaml(
144201

145202
const auto& entry = root[identifier];
146203

147-
Pose convergence_offset = load_pose_from_yaml(file_path, identifier);
148-
149-
const auto mode = static_cast<WaypointMode>(entry["mode"].as<uint8_t>());
204+
const auto mode = load_mode(entry);
205+
const Pose convergence_offset = load_pose_for_mode(entry, mode);
150206

151207
double convergence_threshold = 0.1;
152208
if (entry["convergence_threshold"]) {

0 commit comments

Comments
 (0)