pattern_generator.cpp
Go to the documentation of this file.
00001 #include <vigir_pattern_generator/pattern_generator.h>
00002 
00003 namespace vigir_footstep_planning
00004 {
00005 PatternGenerator::PatternGenerator(ros::NodeHandle& nh)
00006 {
00007   joystick_handler.reset(new JoystickHandler(nh));
00008 
00009   nh.param("world_frame_id", world_frame_id, std::string("/world"));
00010   nh.param("pattern_generator/number_of_steps", (int&)number_of_steps_needed, 5);
00011 
00012   ros::service::waitForService("step_plan_request");
00013 
00014   // start service clients: TODO use global footstep planner
00015   generate_feet_pose_client = nh.serviceClient<msgs::GenerateFeetPoseService>("generate_feet_pose");
00016   step_plan_request_client = nh.serviceClient<vigir_footstep_planning_msgs::StepPlanRequestService>("step_plan_request");
00017 
00018   // initialize action clients
00019   execute_step_plan_ac.reset(new actionlib::SimpleActionClient<msgs::ExecuteStepPlanAction>("execute_step_plan", true));
00020 
00021   reset();
00022 }
00023 
00024 PatternGenerator::~PatternGenerator()
00025 {}
00026 
00027 msgs::ErrorStatus PatternGenerator::generatePattern(const msgs::StepPlanRequest& step_plan_request, msgs::StepPlan& step_plan)
00028 {
00029   // generate step plan request
00030   msgs::StepPlanRequestService step_plan_request_srv;
00031   step_plan_request_srv.request.plan_request = step_plan_request;
00032 
00033   // send request
00034   if (!step_plan_request_client.call(step_plan_request_srv.request, step_plan_request_srv.response))
00035     return ErrorStatusError(msgs::ErrorStatus::ERR_UNKNOWN, "[PatternGenerator]", "Can't call footstep planner!");
00036 
00037   // return new step plan
00038   if (step_plan_request_srv.response.status.error == msgs::ErrorStatus::NO_ERROR)
00039     step_plan = step_plan_request_srv.response.step_plan;
00040 
00041   return step_plan_request_srv.response.status;
00042 }
00043 
00044 void PatternGenerator::reset()
00045 {
00046   joy_d_step = geometry_msgs::Pose();
00047   joy_d_step.orientation = tf::createQuaternionMsgFromYaw(0.0);
00048 
00049   last_performed_step_index = 0;
00050   first_changeable_step_index = 0;
00051   next_step_index_needed = 0;
00052 
00053   start_feet_pose.reset();
00054   foot_start_step_index_left = 0;
00055   foot_start_step_index_right = 0;
00056   has_new_steps = false;
00057 
00058   clearStepPlan();
00059 
00060   params.enable = false;
00061 }
00062 
00063 void PatternGenerator::setParams(const msgs::PatternGeneratorParameters& params)
00064 {
00065   if (isEnabled() && params.enable)
00066   {
00067     // trigger replanning
00068     bool result = true;
00069     if (isSimulationMode())
00070       result = setNextStartStepIndex(last_performed_step_index+1);
00071     else
00072       result = setNextStartStepIndex(first_changeable_step_index-1);
00073 
00074     if (!result)
00075     {
00076       ROS_ERROR("[PatternGenerator] setParams: Replanning failed due to unknown start step.");
00077       reset();
00078     }
00079   }
00080   else
00081   {
00082     // triggers reset when enabling
00083     setEnabled(params.enable);
00084   }
00085 
00086   this->params = params;
00087 }
00088 
00089 void PatternGenerator::setEnabled(bool enable)
00090 {
00091   // activation
00092   if (!isEnabled() && enable)
00093   {
00094     reset();
00095   }
00096   // deactivation
00097   else if (isEnabled() && !enable)
00098   {
00099     bool result = true;
00100     if (isSimulationMode())
00101       result = setNextStartStepIndex(last_performed_step_index+1);
00102     else
00103       result = setNextStartStepIndex(first_changeable_step_index-1);
00104 
00105     if (result)
00106       generateSteps(0, true);
00107   }
00108 
00109   params.enable = enable;
00110 }
00111 
00112 bool PatternGenerator::isEnabled() const
00113 {
00114   return params.enable;
00115 }
00116 
00117 bool PatternGenerator::isSimulationMode() const
00118 {
00119   return params.simulation_mode;
00120 }
00121 
00122 bool PatternGenerator::hasSteps() const
00123 {
00124   return !newest_step_plan.steps.empty();
00125 }
00126 
00127 bool PatternGenerator::hasNewSteps() const
00128 {
00129   return !newest_step_plan.steps.empty() && has_new_steps;
00130 }
00131 
00132 void PatternGenerator::getCompleteStepPlan(msgs::StepPlan& step_plan) const
00133 {
00134   step_plan = complete_step_plan;
00135 }
00136 
00137 void PatternGenerator::getNewestStepPlan(msgs::StepPlan& step_plan) const
00138 {
00139   has_new_steps = false;
00140   step_plan = newest_step_plan;
00141 }
00142 
00143 bool PatternGenerator::setNextStartStepIndex(int step_index)
00144 {
00145   if (step_index < 0)
00146     return false;
00147   else if (!updateFeetStartPoseByStepMap(step_map, step_index-1) || !updateFeetStartPoseByStepMap(step_map, step_index))
00148     return false;
00149 
00150   return true;
00151 }
00152 
00153 int PatternGenerator::getNextStartStepIndex() const
00154 {
00155   return std::max(foot_start_step_index_left, foot_start_step_index_right);
00156 }
00157 
00158 void PatternGenerator::clearStepPlan()
00159 {
00160   complete_step_plan = msgs::StepPlan();
00161   newest_step_plan = msgs::StepPlan();
00162   step_map.clear();
00163 }
00164 
00165 void PatternGenerator::update(const ros::TimerEvent& timer)
00166 {
00167   // handle joystick input
00168   if (joystick_handler && params.joystick_mode)
00169   {
00170     double yaw = tf::getYaw(joy_d_step.orientation);
00171 
00172     bool enable;
00173     joystick_handler->updateJoystickCommands((timer.current_real - timer.last_real).toSec(), enable, joy_d_step.position.x, joy_d_step.position.y, yaw);
00174     joy_d_step.orientation = tf::createQuaternionMsgFromYaw(yaw);
00175 
00176     setEnabled(enable);
00177   }
00178 
00179   // if not enabled, just do nothing
00180   if (!isEnabled())
00181     return;
00182 
00183   // check if more steps are needed
00184   int queued_steps = getNextStartStepIndex() - last_performed_step_index;
00185   if (queued_steps < static_cast<int>(number_of_steps_needed))
00186     generateSteps(number_of_steps_needed-queued_steps);
00187 
00188   if (isSimulationMode())
00189     last_performed_step_index++;
00190 }
00191 
00192 void PatternGenerator::updateLastPerformedStepIndex(int last_performed_step_index)
00193 {
00194   if (!isSimulationMode())
00195   {
00196     if (last_performed_step_index < 0)
00197     {
00198       ROS_ERROR("[PatternGenerator] updateLastPerformedStepIndex: Stopping due to invalid step indx %i", last_performed_step_index);
00199       reset();
00200     }
00201 
00202     this->last_performed_step_index = last_performed_step_index;
00203   }
00204 }
00205 
00206 void PatternGenerator::updateFirstChangeableStepIndex(int first_changeable_step_index)
00207 {
00208   if (!isSimulationMode())
00209   {
00210     if (first_changeable_step_index < 0)
00211     {
00212       ROS_ERROR("[PatternGenerator] updateFirstChangeableStepIndex: Stopping due to invalid step indx %i", first_changeable_step_index);
00213       setEnabled(false);
00214     }
00215 
00216     this->first_changeable_step_index = first_changeable_step_index;
00217   }
00218 }
00219 
00220 void PatternGenerator::updateFeetStartPose(uint8_t foot_index, const geometry_msgs::Pose& pose)
00221 {
00222   msgs::Foot foot;
00223   foot.header.frame_id = world_frame_id;
00224   foot.header.stamp = ros::Time::now();
00225   foot.foot_index = foot_index;
00226   foot.pose = pose;
00227   updateFeetStartPose(foot);
00228 }
00229 
00230 void PatternGenerator::updateFeetStartPose(const msgs::Foot& foot)
00231 {
00232   if (!start_feet_pose)
00233   {
00234     start_feet_pose.reset(new msgs::Feet());
00235     start_feet_pose->header = foot.header;
00236     start_feet_pose->left.header = foot.header;
00237     start_feet_pose->left.foot_index = msgs::Foot::LEFT;
00238     start_feet_pose->right.header = foot.header;
00239     start_feet_pose->right.foot_index = msgs::Foot::RIGHT;
00240   }
00241 
00242   if (foot.foot_index == msgs::Foot::LEFT)
00243   {
00244     start_feet_pose->left.header = foot.header;
00245     start_feet_pose->left = foot;
00246   }
00247   if (foot.foot_index == msgs::Foot::RIGHT)
00248   {
00249     start_feet_pose->right.header = foot.header;
00250     start_feet_pose->right = foot;
00251   }
00252 }
00253 
00254 void PatternGenerator::updateFeetStartPose(const msgs::Feet& feet)
00255 {
00256   updateFeetStartPose(feet.left);
00257   updateFeetStartPose(feet.right);
00258 
00259   start_feet_pose->header = feet.header;
00260 }
00261 
00262 void PatternGenerator::updateFeetStartPose(const msgs::Step& step)
00263 {
00264   updateFeetStartPose(step.foot);
00265 
00266   start_feet_pose->header = step.header;
00267   if (step.foot.foot_index == msgs::Foot::LEFT)
00268     foot_start_step_index_left = step.step_index;
00269   if (step.foot.foot_index == msgs::Foot::RIGHT)
00270     foot_start_step_index_right = step.step_index;
00271 }
00272 
00273 bool PatternGenerator::updateFeetStartPoseByStepMap(const std::map<unsigned int, msgs::Step>& map, unsigned int step_index)
00274 {
00275   std::map<unsigned int, msgs::Step>::const_iterator itr = map.find(step_index);
00276   if (itr != map.end())
00277   {
00278     updateFeetStartPose(itr->second);
00279     return true;
00280   }
00281   return false;
00282 }
00283 
00284 void PatternGenerator::updateFootstepMap(std::map<unsigned int, msgs::Step>& map, const std::vector<msgs::Step>& vec) const
00285 {
00286   std::vector<msgs::Step>::const_iterator itr = vec.begin();
00287 
00288   if (!map.empty())
00289    itr++;
00290 
00291   for (; itr != vec.end(); itr++)
00292     map[itr->step_index] = *itr;
00293 }
00294 
00295 void PatternGenerator::mapToVectorIndexed(const std::map<unsigned int, msgs::Step>& map, std::vector<msgs::Step>& vec, unsigned int start_index, unsigned int end_index) const
00296 {
00297   double foot_z = 0.0;
00298 
00299   vec.clear();
00300   for (unsigned int step_index = start_index; step_index <= end_index; step_index++)
00301   {
00302     std::map<unsigned int, msgs::Step>::const_iterator itr = map.find(step_index);
00303 
00304     // break if index is missing
00305     if (itr == map.end())
00306       break;
00307 
00308     msgs::Step step = itr->second;
00309 
00311     if (step_index == start_index)
00312       foot_z = step.foot.pose.position.z;
00313     else
00314       step.foot.pose.position.z = foot_z;
00315     vec.push_back(step);
00316   }
00317 }
00318 
00319 void PatternGenerator::generateSteps(unsigned int n, bool close_step)
00320 {
00321   msgs::StepPlanRequestService step_plan_request_srv;
00322   msgs::StepPlanRequest& req = step_plan_request_srv.request.plan_request;
00323 
00324   if (!start_feet_pose)
00325   {
00326     std_msgs::Header header;
00327     header.frame_id = world_frame_id;
00328     header.stamp = ros::Time::now();
00329     msgs::Feet start_feet;
00330     determineStartFeetPose(start_feet, generate_feet_pose_client, header);
00331     updateFeetStartPose(start_feet);
00332   }
00333 
00334   // check command input
00335   geometry_msgs::Pose d_step = params.d_step;
00336   if (params.joystick_mode)
00337     d_step = joy_d_step;
00338 
00339   tf::Quaternion q_tf;
00340   tf::quaternionMsgToTF(d_step.orientation, q_tf);
00341 
00342   double roll, pitch, yaw;
00343   tf::Matrix3x3(q_tf).getRPY(roll, pitch, yaw);
00344 
00345   // determine which foot has to move first
00346   unsigned int next_moving_foot_index = msgs::Foot::LEFT;
00347   if (getNextStartStepIndex() == 0)
00348   {
00349     if (d_step.position.y < 0.0)
00350       next_moving_foot_index = msgs::Foot::LEFT;
00351     else if (d_step.position.y == 0.0 && yaw < 0.0)
00352       next_moving_foot_index = msgs::Foot::RIGHT;
00353   }
00354   else
00355   {
00356     if (foot_start_step_index_left > foot_start_step_index_right)
00357       next_moving_foot_index = msgs::Foot::RIGHT;
00358     else
00359       next_moving_foot_index = msgs::Foot::LEFT;
00360   }
00361 
00362   // generate request message
00363   req.header = start_feet_pose->header;
00364   req.start = *start_feet_pose;
00365   switch (next_moving_foot_index)
00366   {
00367     case msgs::Foot::LEFT:
00368       req.start_step_index = foot_start_step_index_right; // reminder: first moving foot has start_index+1
00369       req.start_foot_selection = msgs::StepPlanRequest::LEFT;
00370       break;
00371     case msgs::Foot::RIGHT:
00372       req.start_step_index = foot_start_step_index_left; // reminder: first moving foot has start_index+1
00373       req.start_foot_selection = msgs::StepPlanRequest::RIGHT;
00374       break;
00375     default:
00376       ROS_ERROR("[PatternGenerator] Unknown foot index '%u'", next_moving_foot_index);
00377       return;
00378   }
00379 
00380   // special case for n = 0
00381   if (n == 0)
00382   {
00383     if (next_moving_foot_index == msgs::Foot::LEFT)
00384       req.pattern_parameters.mode = msgs::PatternParameters::FEET_REALIGN_ON_RIGHT;
00385     else
00386       req.pattern_parameters.mode = msgs::PatternParameters::FEET_REALIGN_ON_LEFT;
00387   }
00388   else
00389   {
00390     req.pattern_parameters.steps = n;
00391     req.pattern_parameters.step_distance_forward = d_step.position.x;
00392     req.pattern_parameters.step_distance_sideward = d_step.position.y;
00393     req.pattern_parameters.turn_angle = yaw;
00394     req.pattern_parameters.close_step = close_step;
00395     req.pattern_parameters.extra_seperation = false;
00396     req.pattern_parameters.override = false; // disable here, it will override too much by now
00397     req.pattern_parameters.roll = roll;
00398     req.pattern_parameters.pitch = pitch;
00399     req.pattern_parameters.mode = msgs::PatternParameters::SAMPLING;
00400   }
00401 
00402   req.planning_mode = msgs::StepPlanRequest::PLANNING_MODE_PATTERN;
00403   req.parameter_set_name = params.parameter_set_name;
00404 
00405   // send request
00406   if (!step_plan_request_client.call(step_plan_request_srv.request, step_plan_request_srv.response))
00407   {
00408     ROS_ERROR("[PatternGenerator] Can't call footstep planner!");
00409     return;
00410   }
00411 
00412   // handle new step plan
00413   if (!step_plan_request_srv.response.step_plan.steps.size())
00414     return;
00415 
00416   updateFootstepMap(step_map, step_plan_request_srv.response.step_plan.steps);
00417 
00418   if (complete_step_plan.steps.empty()) // received step plan first time
00419     complete_step_plan = step_plan_request_srv.response.step_plan;
00420   else // just update steps
00421     mapToVectorIndexed(step_map, complete_step_plan.steps, 0, step_plan_request_srv.response.step_plan.steps.back().step_index);
00422 
00423   newest_step_plan = step_plan_request_srv.response.step_plan;
00424   newest_step_plan.header.stamp = ros::Time::now();
00425   newest_step_plan.header.seq++;
00426   has_new_steps = true;
00427 
00428   if (!setNextStartStepIndex(newest_step_plan.steps.back().step_index))
00429   {
00430     ROS_ERROR("[PatternGenerator] generateSteps: Last step index of recent pattern was wrong. Resetting now!");
00431     reset();
00432   }
00433 }
00434 }


vigir_pattern_generator
Author(s): Alexander Stumpf
autogenerated on Fri Apr 7 2017 02:59:51