ContObjectState RobotState::getObjectStateRelMap(ContBaseState base) const { std::vector<double> angles; SBPLArmModelPtr arm_model; KDL::Frame offset; bool left_arm_dominant = (m_planning_mode == PlanningModes::LEFT_ARM || m_planning_mode == PlanningModes::LEFT_ARM_MOBILE); if (left_arm_dominant){ m_left_arm.getAngles(&angles); arm_model = m_left_arm.getArmModel(); offset = m_left_arm.getObjectOffset().Inverse(); } else { m_right_arm.getAngles(&angles); arm_model = m_right_arm.getArmModel(); offset = m_right_arm.getObjectOffset().Inverse(); } // 10 is the link number for the wrist KDL::Frame to_wrist; arm_model->computeFK(angles, base.body_pose(), 10, &to_wrist); KDL::Frame f = to_wrist * offset; double wr,wp,wy; f.M.GetRPY(wr,wp,wy); return ContObjectState(f.p.x(), f.p.y(), f.p.z(), wr, wp, wy); }
// takes in an ompl state and returns a proper robot state that represents the // same state. bool OMPLPR2Planner::convertFullState(ompl::base::State* state, RobotState& robot_state, ContBaseState& base){ ContObjectState obj_state; // fix the l_arm angles vector<double> init_l_arm(7,0); init_l_arm[0] = (0.038946287971107774); init_l_arm[1] = (1.2146697069025374); init_l_arm[2] = (1.3963556492780154); init_l_arm[3] = -1.1972269899800325; init_l_arm[4] = (-4.616317135720829); init_l_arm[5] = -0.9887266887318599; init_l_arm[6] = 1.1755681069775656; LeftContArmState l_arm(init_l_arm); RightContArmState r_arm; const ompl::base::CompoundState* s = dynamic_cast<const ompl::base::CompoundState*> (state); obj_state.x((*(s->as<VectorState>(0)))[0]); obj_state.y((*(s->as<VectorState>(0)))[1]); obj_state.z((*(s->as<VectorState>(0)))[2]); obj_state.roll((*(s->as<VectorState>(0)))[3]); obj_state.pitch((*(s->as<VectorState>(0)))[4]); obj_state.yaw((*(s->as<VectorState>(0)))[5]); r_arm.setUpperArmRoll((*(s->as<VectorState>(0)))[6]); l_arm.setUpperArmRoll((*(s->as<VectorState>(0)))[7]); base.z((*(s->as<VectorState>(0)))[8]); base.x(s->as<SE2State>(1)->getX()); base.y(s->as<SE2State>(1)->getY()); base.theta(s->as<SE2State>(1)->getYaw()); RobotState seed_state(base, r_arm, l_arm); RobotPosePtr final_state; if (!RobotState::computeRobotPose(obj_state, seed_state, final_state)) return false; robot_state = *final_state; return true; }
bool OMPLPR2Planner::planPathCallback(SearchRequestParams& search_request, int trial_id){ if (m_planner_id == PRM_P) ROS_INFO("running PRM planner!"); if (m_planner_id == RRT) ROS_INFO("running RRT planner!"); if (m_planner_id == RRTSTAR) ROS_INFO("running RRTStar planner!"); planner->clear(); planner->getProblemDefinition()->clearSolutionPaths(); planner->as<ompl::geometric::PRM>()->clearQuery(); search_request.left_arm_start.getAngles(&m_collision_checker->l_arm_init); FullState ompl_start(fullBodySpace); FullState ompl_goal(fullBodySpace); if (!createStartGoal(ompl_start, ompl_goal, search_request)) return false; pdef->clearGoal(); pdef->clearStartStates(); pdef->setStartAndGoalStates(ompl_start,ompl_goal); ompl::base::GoalState* temp_goal = new ompl::base::GoalState(planner->getSpaceInformation()); temp_goal->setState(ompl_goal); ompl::base::GoalPtr temp_goal2(temp_goal); // something about different planner types here //if(planner_id_==2 || planner_id_==3){ pdef->setGoal(temp_goal2); //} double t0 = ros::Time::now().toSec(); planner->solve(60.0); double t1 = ros::Time::now().toSec(); double planning_time = t1-t0; ompl::base::PathPtr path = planner->getProblemDefinition()->getSolutionPath(); RRTData data; if (path){ ROS_INFO("OMPL found a solution!"); data.planned = true; ompl::geometric::PathGeometric geo_path = static_cast<ompl::geometric::PathGeometric&>(*path); double t2 = ros::Time::now().toSec(); bool b1 = pathSimplifier->reduceVertices(geo_path); bool b2 = pathSimplifier->collapseCloseVertices(geo_path); bool b3 = pathSimplifier->shortcutPath(geo_path); //ROS_ERROR("shortcut:%d\n",b3); double t3 = ros::Time::now().toSec(); double reduction_time = t3-t2; data.plan_time = planning_time; data.shortcut_time = reduction_time; vector<RobotState> robot_states; vector<ContBaseState> base_states; geo_path.interpolate(); for(unsigned int i=0; i<geo_path.getStateCount(); i++){ ompl::base::State* state = geo_path.getState(i); RobotState robot_state; ContBaseState base; if (!convertFullState(state, robot_state, base)){ ROS_ERROR("ik failed on path reconstruction!"); } vector<double> l_arm, r_arm; robot_states.push_back(robot_state); base_states.push_back(base); robot_state.right_arm().getAngles(&r_arm); robot_state.left_arm().getAngles(&l_arm); BodyPose bp = base.body_pose(); Visualizer::pviz->visualizeRobot(r_arm, l_arm, bp, 150, "robot", 0); usleep(10000); } data.robot_state = robot_states; data.base = base_states; data.path_length = geo_path.getStateCount(); m_stats_writer.write(trial_id, data); } else { data.planned = false; ROS_ERROR("failed to plan"); return false; } return true; }
double ContBaseState::distance(const ContBaseState& start, const ContBaseState& end){ double dX = end.x() - start.x(); double dY = end.y() - start.y(); double dZ = end.z() - start.z(); return pow((pow(dX,2) + pow(dY,2) + pow(dZ,2)),.5); }
// returns <num_steps> number of interpolated points, with the start and end // included in this count. That's why we subtract 1 from the input number. vector<ContBaseState> ContBaseState::interpolate(const ContBaseState& start, const ContBaseState& end, int num_steps){ vector<ContBaseState> interp_steps; if (num_steps < 2){ interp_steps.push_back(start); interp_steps.push_back(end); return interp_steps; } num_steps--; double dX = end.x() - start.x(); double dY = end.y() - start.y(); double dZ = end.z() - start.z(); double dTheta = angles::shortest_angular_distance(start.theta(), end.theta()); double step_mult = 1/static_cast<double>(num_steps); for (int i=0; i <= num_steps; i++){ ContBaseState state(start.x() + i*dX*step_mult, start.y() + i*dY*step_mult, start.z() + i*dZ*step_mult, start.theta() + i*dTheta*step_mult); interp_steps.push_back(state); } return interp_steps; }