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   min_vel_x_ = nh.param("pattern_generator/limits/x/min", -0.1);
00013   max_vel_x_ = nh.param("pattern_generator/limits/x/max",  0.1);
00014   max_vel_y_ = nh.param("pattern_generator/limits/y",  0.1);
00015   max_vel_yaw_ = nh.param("pattern_generator/limits/yaw",  0.1);
00016 
00017   ros::service::waitForService("step_plan_request");
00018 
00019   // start service clients: TODO use global footstep planner
00020   generate_feet_pose_client_ = nh.serviceClient<msgs::GenerateFeetPoseService>("generate_feet_pose");
00021   step_plan_request_client_ = nh.serviceClient<vigir_footstep_planning_msgs::StepPlanRequestService>("step_plan_request");
00022 
00023   // initialize action clients
00024   execute_step_plan_ac_.reset(new actionlib::SimpleActionClient<msgs::ExecuteStepPlanAction>("execute_step_plan", true));
00025 
00026   reset();
00027 }
00028 
00029 PatternGenerator::~PatternGenerator()
00030 {}
00031 
00032 msgs::ErrorStatus PatternGenerator::generatePattern(const msgs::StepPlanRequest& step_plan_request, msgs::StepPlan& step_plan)
00033 {
00034   // generate step plan request
00035   msgs::StepPlanRequestService step_plan_request_srv;
00036   step_plan_request_srv.request.plan_request = step_plan_request;
00037 
00038   // send request
00039   if (!step_plan_request_client_.call(step_plan_request_srv.request, step_plan_request_srv.response))
00040     return ErrorStatusError(msgs::ErrorStatus::ERR_UNKNOWN, "[PatternGenerator]", "Can't call footstep planner!");
00041 
00042   // return new step plan
00043   if (step_plan_request_srv.response.status.error == msgs::ErrorStatus::NO_ERROR)
00044     step_plan = step_plan_request_srv.response.step_plan;
00045 
00046   return step_plan_request_srv.response.status;
00047 }
00048 
00049 void PatternGenerator::reset()
00050 {
00051   joystick_cmd_ = geometry_msgs::Twist();
00052 
00053   first_changeable_step_index_ = 0;
00054   next_step_index_needed_ = 0;
00055 
00056   start_feet_pose_.reset();
00057   foot_start_step_index_left_ = 0;
00058   foot_start_step_index_right_ = 0;
00059   has_new_steps_ = false;
00060 
00061   clearStepPlan();
00062 
00063   params_.enable = false;
00064 }
00065 
00066 void PatternGenerator::setParams(const msgs::PatternGeneratorParameters& params)
00067 {
00068   if (isEnabled() && params.enable)
00069   {
00070     // trigger replanning
00071 //    if (!setNextStartStepIndex(first_changeable_step_index_))
00072 //    {
00073 //      ROS_ERROR("[PatternGenerator] setParams: Replanning failed due to unknown start step.");
00074 //      reset();
00075 //    }
00076   }
00077   else
00078   {
00079     // triggers reset when enabling
00080     setEnabled(params.enable);
00081   }
00082 
00083   params_ = params;
00084 }
00085 
00086 void PatternGenerator::setEnabled(bool enable)
00087 {
00088   // activation
00089   if (!isEnabled() && enable)
00090     reset();
00091   // deactivation
00092   else if (isEnabled() && !enable)
00093     generateSteps(0);
00094 
00095   params_.enable = enable;
00096 }
00097 
00098 bool PatternGenerator::isEnabled() const
00099 {
00100   return params_.enable;
00101 }
00102 
00103 bool PatternGenerator::isSimulationMode() const
00104 {
00105   return params_.simulation_mode;
00106 }
00107 
00108 bool PatternGenerator::hasSteps() const
00109 {
00110   return !last_step_sequence_.steps.empty();
00111 }
00112 
00113 bool PatternGenerator::hasNewSteps() const
00114 {
00115   return !last_step_sequence_.steps.empty() && has_new_steps_;
00116 }
00117 
00118 void PatternGenerator::getCompleteStepPlan(msgs::StepPlan& step_plan) const
00119 {
00120   step_plan_.toMsg(step_plan);
00121 }
00122 
00123 void PatternGenerator::getLastStepSequence(msgs::StepPlan& step_plan) const
00124 {
00125   has_new_steps_ = false;
00126   step_plan = last_step_sequence_;
00127 }
00128 
00129 int PatternGenerator::getNextStartStepIndex() const
00130 {
00131   return std::max(foot_start_step_index_left_, foot_start_step_index_right_);
00132 }
00133 
00134 void PatternGenerator::clearStepPlan()
00135 {
00136   step_plan_.clear();
00137   last_step_sequence_ = msgs::StepPlan();
00138 }
00139 
00140 void PatternGenerator::update(const ros::TimerEvent& /*timer*/)
00141 {
00142   // (timer.current_real - timer.last_real).toSec()
00143 
00144   // handle joystick input
00145   if (joystick_handler_ && params_.joystick_mode)
00146   {
00147     bool enable;
00148     joystick_handler_->getJoystickCommand(joystick_cmd_, enable);
00149 
00150     setEnabled(enable);
00151   }
00152 
00153   // if not enabled, just do nothing
00154   if (!isEnabled())
00155     return;
00156 
00157   // check if more steps are needed
00158   generateSteps(number_of_steps_needed_);
00159 
00160   if (isSimulationMode())
00161     updateFirstChangeableStepIndex(first_changeable_step_index_+1);
00162 }
00163 
00164 void PatternGenerator::updateFirstChangeableStepIndex(int first_changeable_step_index)
00165 {
00166   if (!isEnabled())
00167     return;
00168 
00169   if (first_changeable_step_index < 0)
00170   {
00171     ROS_ERROR("[PatternGenerator] updateFirstChangeableStepIndex: Stopping due to invalid step index %i", first_changeable_step_index);
00172     setEnabled(false);
00173   }
00174 
00175   first_changeable_step_index_ = first_changeable_step_index;
00176 
00177   msgs::Step step;
00178   if (first_changeable_step_index_ > 0)
00179   {
00180     if (step_plan_.getStep(step, first_changeable_step_index_-1))
00181       updateFeetStartPose(step);
00182     else
00183     {
00184       ROS_ERROR("[PatternGenerator] updateFirstChangeableStepIndex: Internal error; step %i isn't in step plan.", first_changeable_step_index);
00185       setEnabled(false);
00186     }
00187   }
00188 
00189   if (step_plan_.getStep(step, first_changeable_step_index_))
00190     updateFeetStartPose(step);
00191   else
00192   {
00193     ROS_ERROR("[PatternGenerator] updateFirstChangeableStepIndex: Internal error; step %i isn't in step plan.", first_changeable_step_index);
00194     setEnabled(false);
00195   }
00196 }
00197 
00198 void PatternGenerator::updateFeetStartPose(const msgs::Foot& foot)
00199 {
00200   if (!start_feet_pose_)
00201   {
00202     start_feet_pose_.reset(new msgs::Feet());
00203     start_feet_pose_->header = foot.header;
00204     start_feet_pose_->left.header = foot.header;
00205     start_feet_pose_->left.foot_index = msgs::Foot::LEFT;
00206     start_feet_pose_->right.header = foot.header;
00207     start_feet_pose_->right.foot_index = msgs::Foot::RIGHT;
00208   }
00209 
00210   if (foot.foot_index == msgs::Foot::LEFT)
00211   {
00212     start_feet_pose_->left.header = foot.header;
00213     start_feet_pose_->left = foot;
00214   }
00215   if (foot.foot_index == msgs::Foot::RIGHT)
00216   {
00217     start_feet_pose_->right.header = foot.header;
00218     start_feet_pose_->right = foot;
00219   }
00220 }
00221 
00222 void PatternGenerator::updateFeetStartPose(const msgs::Feet& feet)
00223 {
00224   updateFeetStartPose(feet.left);
00225   updateFeetStartPose(feet.right);
00226 
00227   start_feet_pose_->header = feet.header;
00228 }
00229 
00230 void PatternGenerator::updateFeetStartPose(const msgs::Step& step)
00231 {
00232   updateFeetStartPose(step.foot);
00233 
00234   start_feet_pose_->header = step.header;
00235   if (step.foot.foot_index == msgs::Foot::LEFT)
00236     foot_start_step_index_left_ = step.step_index;
00237   if (step.foot.foot_index == msgs::Foot::RIGHT)
00238     foot_start_step_index_right_ = step.step_index;
00239 }
00240 
00241 void PatternGenerator::generateSteps(unsigned int n)
00242 {
00243   msgs::StepPlanRequestService step_plan_request_srv;
00244   msgs::StepPlanRequest& req = step_plan_request_srv.request.plan_request;
00245 
00246   if (!start_feet_pose_)
00247   {
00248     std_msgs::Header header;
00249     header.frame_id = world_frame_id_;
00250     header.stamp = ros::Time::now();
00251     msgs::Feet start_feet;
00252     determineStartFeetPose(start_feet, generate_feet_pose_client_, header);
00253     updateFeetStartPose(start_feet);
00254   }
00255 
00256   // check command input
00257   geometry_msgs::Twist cmd = params_.joystick_mode ? joystick_cmd_ : params_.cmd;
00258 
00259   if (cmd.linear.x > 0.0)
00260     cmd.linear.x *= max_vel_x_;
00261   else
00262     cmd.linear.x *= -min_vel_x_;
00263 
00264   cmd.linear.y *= max_vel_y_;
00265   cmd.angular.z *= max_vel_yaw_;
00266 
00267   // determine which foot has to move first (note: For the planner the start foot is fixed, thus, the first moved foot is start+1)
00268   unsigned int next_moving_foot_index = msgs::Foot::LEFT;
00269   if (getNextStartStepIndex() == 0 || ((cmd.linear.y != 0.0 || cmd.angular.z != 0.0) && number_of_steps_needed_ > 2))
00270   {
00271     if (cmd.linear.y < 0.0 || (cmd.linear.y == 0.0 && cmd.angular.z < 0.0))
00272       next_moving_foot_index = msgs::Foot::RIGHT;
00273     else
00274       next_moving_foot_index = msgs::Foot::LEFT;
00275   }
00276   else
00277   {
00278     if (foot_start_step_index_left_ < foot_start_step_index_right_) // the higher index is pointing on first changeable index
00279       next_moving_foot_index = msgs::Foot::RIGHT;
00280     else
00281       next_moving_foot_index = msgs::Foot::LEFT;
00282   }
00283 
00284   // generate request message
00285   req.header = start_feet_pose_->header;
00286   req.start = *start_feet_pose_;
00287   switch (next_moving_foot_index)
00288   {
00289     case msgs::Foot::LEFT:
00290       req.start_step_index = foot_start_step_index_right_; // reminder: first moving foot has start_index+1
00291       req.start_foot_selection = msgs::StepPlanRequest::LEFT;
00292       break;
00293     case msgs::Foot::RIGHT:
00294       req.start_step_index = foot_start_step_index_left_; // reminder: first moving foot has start_index+1
00295       req.start_foot_selection = msgs::StepPlanRequest::RIGHT;
00296       break;
00297     default:
00298       ROS_ERROR("[PatternGenerator] Unknown foot index '%u'", next_moving_foot_index);
00299       return;
00300   }
00301 
00302   // special case for n = 0
00303   if (n == 0)
00304   {
00305     if (next_moving_foot_index == msgs::Foot::LEFT)
00306       req.pattern_parameters.mode = msgs::PatternParameters::FEET_REALIGN_ON_RIGHT;
00307     else
00308       req.pattern_parameters.mode = msgs::PatternParameters::FEET_REALIGN_ON_LEFT;
00309   }
00310   else
00311   {
00312     req.pattern_parameters.steps = n;
00313     req.pattern_parameters.step_distance_forward = cmd.linear.x;
00314     req.pattern_parameters.step_distance_sideward = cmd.linear.y;
00315     req.pattern_parameters.turn_angle = cmd.angular.z;
00316     req.pattern_parameters.close_step = true;
00317     req.pattern_parameters.extra_seperation = false;
00318     req.pattern_parameters.override = false; // disable here, it will override too much by now
00319     req.pattern_parameters.roll = 0.0;
00320     req.pattern_parameters.pitch = 0.0;
00321     req.pattern_parameters.mode = msgs::PatternParameters::SAMPLING;
00322   }
00323 
00324   //ROS_INFO_STREAM(req);
00325 
00326   req.planning_mode = msgs::StepPlanRequest::PLANNING_MODE_PATTERN;
00327   req.parameter_set_name = params_.parameter_set_name;
00328 
00329   // send request
00330   if (!step_plan_request_client_.call(step_plan_request_srv.request, step_plan_request_srv.response))
00331   {
00332     ROS_ERROR("[PatternGenerator] Can't call footstep planner!");
00333     return;
00334   }
00335 
00336   // handle new step plan
00337   if (!step_plan_request_srv.response.step_plan.steps.size())
00338   {
00339     ROS_ERROR("[PatternGenerator] Received empty plan!");
00340     return;
00341   }
00342 
00343   last_step_sequence_ = step_plan_request_srv.response.step_plan;
00344   has_new_steps_ = true;
00345 
00346   if (params_.ignore_invalid_steps)
00347   {
00348     for (msgs::Step& step : last_step_sequence_.steps)
00349       step.valid = true;
00350   }
00351 
00352   step_plan_.updateStepPlan(last_step_sequence_);
00353   step_plan_.removeSteps(last_step_sequence_.steps.back().step_index+1);
00354 }
00355 }


vigir_pattern_generator
Author(s): Alexander Stumpf
autogenerated on Thu Jun 6 2019 18:38:16