walk_analyzer.cpp
Go to the documentation of this file.
2 
4 {
6 {
7  nh.getParam("logging_dir", logging_dir);
8  //data_header = "index step_x step_y step_z droll dpitch dyaw distance_2D distance_3D duration swing_height";
9  data_header = "index | step_x step_y step_yaw | dx dy dyaw | swing_distance duration";
10  reset();
11 }
12 
14 {
15 }
16 
18 {
19  current_goal_id = actionlib_msgs::GoalID();
20  current_step_plan = msgs::StepPlan();
21  step_feedback_map.clear();
22 }
23 
24 void WalkAnalyzer::executeStepPlanGoalCallback(const msgs::ExecuteStepPlanActionGoal& execute_goal)
25 {
26  // check if new step plan is executed
27  if (execute_goal.goal_id.id != current_goal_id.id || execute_goal.goal_id.stamp != current_goal_id.stamp)
28  {
29  if (!step_feedback_map.empty())
31  reset();
32  }
33  else
34  return;
35 
36  if (!execute_goal.goal.step_plan.steps.empty())
37  {
38  current_goal_id = execute_goal.goal_id;
39  current_step_plan = execute_goal.goal.step_plan;
40 
41  const msgs::Step& initial = current_step_plan.steps.front();
42 
43  msgs::Step start_left, start_right;
44  start_left.foot = current_step_plan.start.left;
45  start_right.foot = current_step_plan.start.right;
46 
47  // adding initial states
48  step_feedback_map[initial.step_index-1] = initial.foot.foot_index == msgs::Foot::LEFT ? start_right : start_left;
49  step_feedback_map[initial.step_index] = initial.foot.foot_index == msgs::Foot::LEFT ? start_left : start_right;
50 
51  ROS_INFO("[WalkAnalyzer] Got new step plan with %lu steps.", current_step_plan.steps.size());
52  }
53 }
54 
55 void WalkAnalyzer::executeStepPlanResultCallback(const msgs::ExecuteStepPlanActionResult& execute_result)
56 {
57  if (!step_feedback_map.empty())
59  reset();
60 }
61 
62 void WalkAnalyzer::stepFeedbackCallback(const msgs::StepPlanFeedback& feedback)
63 {
64  if (current_step_plan.steps.empty() || feedback.steps.empty())
65  return;
66 
67  for (std::vector<msgs::Step>::const_iterator itr = feedback.steps.begin(); itr != feedback.steps.end(); itr++)
68  {
69  if (itr->step_index <= current_step_plan.steps.back().step_index)
70  step_feedback_map[itr->step_index] = *itr;
71  }
72 }
73 
74 bool WalkAnalyzer::analyze(const msgs::Step& previous, const msgs::Step& current, const msgs::Step& next, std::string& result) const
75 {
76  std::ostringstream ss;
77  ss << std::fixed << std::setprecision(6);
78  std::ostringstream temp;
79  temp << std::fixed << std::setprecision(6);
80 
81  // get travel distance
82  geometry_msgs::Pose dswing;
83  getDeltaStep(previous.foot, next.foot, dswing);
84 
85  tf::Quaternion swing_q;
86  tf::quaternionMsgToTF(dswing.orientation, swing_q);
87 
88  double swing_r, swing_p, swing_y;
89  tf::Matrix3x3(swing_q).getRPY(swing_r, swing_p, swing_y);
90 
91  // reconstruct delta step
92  geometry_msgs::Pose dstep;
93  getDeltaStep(current.foot, next.foot, dstep);
94 
95  tf::Quaternion step_q;
96  tf::quaternionMsgToTF(dstep.orientation, step_q);
97 
98  double step_r, step_p, step_y;
99  tf::Matrix3x3(step_q).getRPY(step_r, step_p, step_y);
100 
101  // generate message
102  ss << next.step_index << " | "
103  << dstep.position.x << " " << dstep.position.y << " "
104  /*<< r << " " << p << " "*/ << step_y << " | "
105  << dswing.position.x << " " << dswing.position.y << " " //<< dstep.position.z << " "
106  /*<< r << " " << p << " "*/ << swing_y << " | "
107  << sqrt(dswing.position.x*dswing.position.x + dswing.position.y*dswing.position.y) << " "
108  //<< sqrt(dstep.position.x*dstep.position.x + dstep.position.y*dstep.position.y + dstep.position.z*dstep.position.z) << " "
109  << next.step_duration;// << " " << next.swing_height;
110 
111  if (!temp.str().empty())
112  temp << ", ";
113 
114  temp << "{" << sqrt(dswing.position.x*dswing.position.x + dswing.position.y*dswing.position.y) << ", " << next.step_duration << "}";
115 
116  //ss << "\n" << temp.str();
117 
118  result = ss.str();
119 
120  return true;
121 }
122 
123 bool WalkAnalyzer::analyzeData(const std::map<int, msgs::Step>& data, std::string& result) const
124 {
125  result.clear();
126 
127  if (data.empty())
128  return false;
129 
130  if (data.size() < 3)
131  return true;
132 
133  std::map<int, msgs::Step>::const_iterator itr = data.begin();
134  msgs::Step previous = itr->second; itr++;
135  msgs::Step current = itr->second; itr++;
136 
137  for (; itr != data.end(); itr++)
138  {
139  const msgs::Step& next = itr->second;
140 
141  if (current.step_index+1 != next.step_index)
142  {
143  ROS_ERROR("[WalkAnalyzer] analyzeData: Inconsistent data record! Stopping analysis.");
144  return false;
145  }
146 
147  std::string temp;
148  if (!analyze(previous, current, next, temp))
149  return false;
150 
151  if (!result.empty())
152  result += "\n";
153  result += temp;
154 
155  previous = current;
156  current = next;
157  }
158 
159  return true;
160 }
161 
162 void WalkAnalyzer::writeResult(const std::string& logging_dir, const std::string& data_header)
163 {
164  std::string result;
165  if (!analyzeData(step_feedback_map, result))
166  {
167  ROS_ERROR("[WalkAnalyzer] Error while analyzing data!");
168  return;
169  }
170  if (result.empty())
171  return;
172 
173  std::string date_time = currentDateTime();
174 
175  // write to seperate file
176  std::string filename = logging_dir + "/" + date_time + ".txt";
177  std::ofstream file(filename);
178 
179  if (file.is_open())
180  {
181  file << data_header + "\n";
182  file << result;
183  file.close();
184  ROS_INFO("[WalkAnalyzer] Written step plan result in '%s'", filename.c_str());
185  }
186  else
187  ROS_ERROR("[WalkAnalyzer] Can't open file '%s'", filename.c_str());
188 
189  // append to total file
190  filename = logging_dir + "/overall.txt";
191  file.open(filename, std::ios_base::app);
192 
193  if (file.is_open())
194  {
195  file << result << "\n";
196  file.close();
197  ROS_INFO("[WalkAnalyzer] Written step plan result in '%s'", filename.c_str());
198  }
199  else
200  ROS_ERROR("[WalkAnalyzer] Can't open file '%s'", filename.c_str());
201 }
202 
203 std::string WalkAnalyzer::currentDateTime() const
204 {
205  time_t now = time(0);
206  struct tm tstruct;
207  char buf[80];
208  tstruct = *localtime(&now);
209  strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
210 
211  return buf;
212 }
213 }
filename
virtual bool analyze(const msgs::Step &previous, const msgs::Step &current, const msgs::Step &next, std::string &result) const
void executeStepPlanGoalCallback(const msgs::ExecuteStepPlanActionGoal &execute_goal)
actionlib_msgs::GoalID current_goal_id
Definition: walk_analyzer.h:77
std::map< int, msgs::Step > step_feedback_map
Definition: walk_analyzer.h:80
static void quaternionMsgToTF(const geometry_msgs::Quaternion &msg, Quaternion &bt)
void getRPY(tfScalar &roll, tfScalar &pitch, tfScalar &yaw, unsigned int solution_number=1) const
#define ROS_INFO(...)
void writeResult(const std::string &logging_dir, const std::string &data_header)
void stepFeedbackCallback(const msgs::StepPlanFeedback &feedback)
bool getParam(const std::string &key, std::string &s) const
void executeStepPlanResultCallback(const msgs::ExecuteStepPlanActionResult &execute_result)
#define ROS_ERROR(...)
bool analyzeData(const std::map< int, msgs::Step > &data, std::string &result) const


vigir_walk_monitor
Author(s): Alexander Stumpf
autogenerated on Sun Nov 17 2019 03:30:09