Skip to content

Commit b39a6cb

Browse files
committed
logger - whole planned path is saved by the GlobalPlannerLogger
1 parent d27dda7 commit b39a6cb

File tree

3 files changed

+100
-12
lines changed

3 files changed

+100
-12
lines changed

srpb_logger/include/srpb_logger/global_planner_data.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <geometry_msgs/PoseStamped.h>
44
#include <tf2/utils.h>
55

6+
#include <vector>
7+
68
namespace srpb {
79
namespace logger {
810

@@ -13,21 +15,21 @@ class GlobalPlannerData {
1315
const geometry_msgs::PoseStamped& goal_pose,
1416
bool planning_success,
1517
double planning_time,
16-
size_t plan_size
17-
): GlobalPlannerData(robot_pose.pose, goal_pose.pose, planning_success, planning_time, plan_size) {}
18+
const std::vector<geometry_msgs::PoseStamped>& plan
19+
): GlobalPlannerData(robot_pose.pose, goal_pose.pose, planning_success, planning_time, plan) {}
1820

1921
GlobalPlannerData(
2022
const geometry_msgs::Pose& robot_pose,
2123
const geometry_msgs::Pose& goal_pose,
2224
bool planning_success,
2325
double planning_time,
24-
size_t plan_size
26+
const std::vector<geometry_msgs::PoseStamped>& plan
2527
):
2628
pose_(robot_pose),
2729
goal_(goal_pose),
2830
planning_success_(planning_success),
2931
planning_time_(planning_time),
30-
plan_size_(plan_size)
32+
plan_(plan)
3133
{}
3234

3335
inline geometry_msgs::Pose getPose() const {
@@ -88,17 +90,27 @@ class GlobalPlannerData {
8890
return planning_time_;
8991
}
9092

91-
/// Number of poses the global path plan consists of
93+
/// Returns a copy of a container with the global path plan @ref plan_
94+
inline std::vector<geometry_msgs::PoseStamped> getPlan() const {
95+
return plan_;
96+
}
97+
98+
/// Returns a const reference to a container with the global path plan @ref plan_
99+
inline const std::vector<geometry_msgs::PoseStamped>& getPlanCref() const {
100+
return plan_;
101+
}
102+
103+
/// Number of poses the global path plan @ref plan_ is expected to contain
92104
inline size_t getPlanSize() const {
93-
return plan_size_;
105+
return plan_.size();
94106
}
95107

96108
protected:
97109
bool planning_success_;
98110
geometry_msgs::Pose pose_;
99111
geometry_msgs::Pose goal_;
100112
double planning_time_;
101-
size_t plan_size_;
113+
std::vector<geometry_msgs::PoseStamped> plan_;
102114
};
103115

104116
} // namespace logger

srpb_logger/src/global_planner_logger.cpp

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,35 @@ std::string GlobalPlannerLogger::plannerToString(const GlobalPlannerData& planne
5656
/* 8 */ ss << std::setw(4) << std::setprecision(1) << static_cast<double>(planner.getPlanningStatus()) << " ";
5757
/* 9 */ ss << std::setw(9) << std::setprecision(4) << planner.getPlanningTime() << " ";
5858
/* 10 */ ss << std::setw(9) << std::setprecision(1) << planner.getPlanSize();
59+
60+
// dynamic size of the plan
61+
ss << " / ";
62+
const auto& plan = planner.getPlanCref();
63+
for (const auto& pose_stamped: plan) {
64+
ss << " " << std::setw(9) << std::setprecision(4) << pose_stamped.pose.position.x;
65+
ss << " " << std::setw(9) << std::setprecision(4) << pose_stamped.pose.position.y;
66+
ss << " " << std::setw(9) << std::setprecision(4) << tf2::getYaw(pose_stamped.pose.orientation);
67+
}
5968
return ss.str();
6069
}
6170

6271
std::pair<bool, GlobalPlannerData> GlobalPlannerLogger::plannerFromString(const std::string& str) {
63-
auto vals = people_msgs_utils::parseString<double>(str, " ");
64-
if (vals.size() != 11) {
72+
// divide into 2 parts considering separator
73+
size_t separator = str.find("/");
74+
auto vals = people_msgs_utils::parseString<double>(str.substr(0, separator - 1), " ");
75+
auto vals_plan_poses = people_msgs_utils::parseString<double>(str.substr(separator + 1), " ");
76+
77+
// static part of the entry has always the same length; a dynamic part must have 3 elements for each pose
78+
bool plan_poses_in_triplets = vals_plan_poses.size() % 3 != 0;
79+
if (vals.size() != 11 || plan_poses_in_triplets) {
6580
std::cout << "\x1B[31mFound corrupted data of a global planner:\r\n\t" << str << "\x1B[0m" << std::endl;
6681
// dummy planner data
6782
auto dummy_planner = GlobalPlannerData(
6883
geometry_msgs::Pose(),
6984
geometry_msgs::Pose(),
7085
false,
7186
0.0,
72-
0
87+
std::vector<geometry_msgs::PoseStamped>()
7388
);
7489
return {false, dummy_planner};
7590
}
@@ -97,9 +112,31 @@ std::pair<bool, GlobalPlannerData> GlobalPlannerLogger::plannerFromString(const
97112

98113
bool planning_status = static_cast<bool>(static_cast<int>(vals.at(8)));
99114
double planning_time = vals.at(9);
115+
100116
double plan_size = vals.at(10);
117+
std::vector<geometry_msgs::PoseStamped> plan;
118+
// each pose is represented by a triplet
119+
for (
120+
auto it = vals_plan_poses.cbegin();
121+
it != vals_plan_poses.cend();
122+
it = it + 3
123+
) {
124+
double x = *it;
125+
double y = *(it+1);
126+
double yaw = *(it+2);
127+
geometry_msgs::PoseStamped pose;
128+
pose.pose.position.x = x;
129+
pose.pose.position.y = y;
130+
131+
// NOTE: ctor of tf2::Quaternion using Euler angles is deprecated
132+
tf2::Quaternion quat;
133+
quat.setEuler(0.0, 0.0, yaw);
134+
pose.pose.orientation = tf2::toMsg(quat);
135+
136+
plan.push_back(pose);
137+
}
101138

102-
auto planner = GlobalPlannerData(pose, goal, planning_status, planning_time, plan_size);
139+
auto planner = GlobalPlannerData(pose, goal, planning_status, planning_time, plan);
103140
return {true, planner};
104141
}
105142

srpb_logger/test/test_global_planner_logger.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <gtest/gtest.h>
22

33
#include <srpb_logger/global_planner_logger.h>
4+
#include <angles/angles.h>
45

56
using namespace srpb::logger;
67

@@ -33,8 +34,27 @@ TEST(ConversionTest, planner) {
3334
bool planning_success = true;
3435
double planning_time = 0.135;
3536
size_t plan_size = 497;
37+
// create a arbitrary path plan
38+
std::vector<geometry_msgs::PoseStamped> plan;
39+
plan.resize(plan_size);
40+
double x_plan = -5.159;
41+
double y_plan = 20.951;
42+
double yaw_plan = 0.357;
43+
for (auto& pose_stamped: plan) {
44+
// modify vector element
45+
pose_stamped.pose.position.x = x_plan;
46+
pose_stamped.pose.position.y = y_plan;
47+
// NOTE: ctor of tf2::Quaternion using Euler angles is deprecated
48+
tf2::Quaternion quat;
49+
quat.setEuler(0.0, 0.0, yaw_plan);
50+
pose_stamped.pose.orientation = tf2::toMsg(quat);
51+
// prep coords for the next iteration
52+
x_plan += 0.142;
53+
y_plan -= 0.249;
54+
yaw_plan = angles::normalize_angle(yaw_plan + 0.029);
55+
}
3656

37-
GlobalPlannerData data_in(pose, goal, planning_success, planning_time, plan_size);
57+
GlobalPlannerData data_in(pose, goal, planning_success, planning_time, plan);
3858

3959
// 1. evaluate if attributes were saved correctly
4060
ASSERT_EQ(data_in.getPositionX(), pose.position.x);
@@ -51,6 +71,7 @@ TEST(ConversionTest, planner) {
5171
ASSERT_EQ(data_in.getPlanningStatus(), planning_success);
5272
ASSERT_EQ(data_in.getPlanningTime(), planning_time);
5373
ASSERT_EQ(data_in.getPlanSize(), plan_size);
74+
ASSERT_EQ(data_in.getPlan(), plan);
5475

5576
auto data_in_str = GlobalPlannerLogger::plannerToString(data_in);
5677
auto conversion = GlobalPlannerLogger::plannerFromString(data_in_str);
@@ -74,6 +95,24 @@ TEST(ConversionTest, planner) {
7495
ASSERT_EQ(data_out.getPlanningStatus(), data_in.getPlanningStatus());
7596
ASSERT_EQ(data_out.getPlanningTime(), data_in.getPlanningTime());
7697
ASSERT_EQ(data_out.getPlanSize(), data_in.getPlanSize());
98+
/* NOTE: cannot simply use:
99+
* ASSERT_EQ(data_out.getPlan(), data_in.getPlan());
100+
* here, as it uses a serialized version (?) of the message structure; despite the same contents (with 1e-04
101+
* accuracy), there may be some whitespace differences
102+
*/
103+
auto out_plan = data_out.getPlanCref();
104+
auto in_plan = data_in.getPlanCref();
105+
for (
106+
auto out_it = out_plan.cbegin(), in_it = in_plan.cbegin();
107+
out_it != out_plan.cend() || in_it != in_plan.cend();
108+
out_it++, in_it++
109+
) {
110+
auto out_pose = *out_it;
111+
auto in_pose = *in_it;
112+
ASSERT_NEAR(out_pose.pose.position.x, in_pose.pose.position.x, 1e-04);
113+
ASSERT_NEAR(out_pose.pose.position.y, in_pose.pose.position.y, 1e-04);
114+
ASSERT_NEAR(tf2::getYaw(out_pose.pose.orientation), tf2::getYaw(in_pose.pose.orientation), 1e-04);
115+
}
77116
}
78117

79118
int main(int argc, char** argv) {

0 commit comments

Comments
 (0)