feet_pose_generator.cpp
Go to the documentation of this file.
00001 #include <vigir_feet_pose_generator/feet_pose_generator.h>
00002 
00003 namespace vigir_footstep_planning
00004 {
00005 FeetPoseGenerator::FeetPoseGenerator(ros::NodeHandle& nh)
00006   : has_robot_pose(false)
00007 {
00008   nh.getParam("foot/separation", foot_separation);
00009 
00010   nh.getParam("foot/left/frame_id", left_foot_frame_id);
00011   nh.getParam("foot/right/frame_id", right_foot_frame_id);
00012 
00013   nh.getParam("foot/left/foot_frame/z", left_foot_shift_z);
00014   nh.getParam("foot/right/foot_frame/z", right_foot_shift_z);
00015 
00016   // strip '/'
00017   strip(left_foot_frame_id, '/');
00018   strip(right_foot_frame_id, '/');
00019 
00020   nh.getParam("pelvis_to_feet_center/x", pelvis_to_feet_center.x);
00021   nh.getParam("pelvis_to_feet_center/y", pelvis_to_feet_center.y);
00022   nh.getParam("pelvis_to_feet_center/z", pelvis_to_feet_center.z);
00023 
00024   // start service clients
00025   transform_feet_poses_client = nh.serviceClient<msgs::TransformFeetPosesService>("transform_feet_poses");
00026 }
00027 
00028 FeetPoseGenerator::~FeetPoseGenerator()
00029 {
00030 }
00031 
00032 void FeetPoseGenerator::setRobotPose(const geometry_msgs::PoseStampedConstPtr &robot_pose)
00033 {
00034   this->robot_pose.header = robot_pose->header;
00035   this->robot_pose = *robot_pose;
00036   has_robot_pose = true;
00037 }
00038 
00039 void FeetPoseGenerator::setRobotPoseWithCovariance(const geometry_msgs::PoseWithCovarianceStampedConstPtr &robot_pose)
00040 {
00041   this->robot_pose.header = robot_pose->header;
00042   this->robot_pose.pose = robot_pose->pose.pose;
00043   has_robot_pose = true;
00044 }
00045 
00046 void FeetPoseGenerator::setTerrainModel(const vigir_terrain_classifier::TerrainModelMsg::ConstPtr& terrain_model)
00047 {
00048   // update terrain model
00049   if (this->terrain_model)
00050     this->terrain_model->fromMsg(*terrain_model);
00051   else
00052     this->terrain_model.reset(new vigir_terrain_classifier::TerrainModel(*terrain_model));
00053 }
00054 
00055 msgs::ErrorStatus FeetPoseGenerator::generateFeetPose(const msgs::FeetPoseRequest& request, msgs::Feet& feet)
00056 {
00057   msgs::ErrorStatus status;
00058 
00059   // strip '/'
00060   std::string request_frame_id = request.header.frame_id;
00061   strip(request_frame_id, '/');
00062 
00063   if (request.flags & msgs::FeetPoseRequest::FLAG_CURRENT)
00064   {
00065     // try to get current feet pose
00066     if (getCurrentFeetPose(feet, request_frame_id))
00067     {
00068       return status;
00069     }
00070     // project robot (pelvis) pose to the ground
00071     else if (has_robot_pose)
00072     {
00073       std::string robot_pose_frame_id = strip_const(robot_pose.header.frame_id, '/');
00074       if (request_frame_id != robot_pose_frame_id)
00075         status += ErrorStatusWarning(msgs::ErrorStatus::WARN_UNKNOWN, "FeetPoseGenerator", "generateFeetPose: Frame ID of robot pose ('" + robot_pose_frame_id + "') and request ('" + request_frame_id + "') mismatch, automatic transformation is not implemented yet!");
00076 
00077       feet = generateFeetPose(robot_pose);
00078       //pelvisToGroundTransform(feet);
00079     }
00080     else
00081     {
00082       return status + ErrorStatusError(msgs::ErrorStatus::ERR_UNKNOWN, "FeetPoseGenerator", "generateFeetPose: No robot pose available for handling FLAG_CURRENT!");
00083     }
00084   }
00085   else
00086   {
00087     geometry_msgs::PoseStamped pose;
00088     pose.header = request.header;
00089     pose.pose = request.pose;
00090     feet = generateFeetPose(pose);
00091   }
00092 
00093   if (request.flags & msgs::FeetPoseRequest::FLAG_PELVIS_FRAME)
00094   {
00095     pelvisToGroundTransform(feet);
00096   }
00097 
00098   if (request.flags & msgs::FeetPoseRequest::FLAG_3D)
00099   {
00100     msgs::ErrorStatus temp_status;
00101     msgs::Feet temp_feet = feet;
00102 
00103     temp_status = updateFeetPose(temp_feet);
00104     if (hasError(temp_status))
00105       status += ErrorStatusWarning(msgs::ErrorStatus::WARN_UNKNOWN, "FeetPoseGenerator", "generateFeetPose: Couldn't determine either 3D nor height of feet!", false);
00106     else
00107     {
00108       status += temp_status;
00109       feet = temp_feet;
00110     }
00111   }
00112 
00113   if (request.flags & msgs::FeetPoseRequest::FLAG_CURRENT_Z)
00114   {
00115     msgs::Feet current_feet;
00116     if (getCurrentFeetPose(current_feet, request_frame_id))
00117     {
00118       feet.left.pose.position.z = current_feet.left.pose.position.z+left_foot_shift_z; // adding shift which is eliminated by transformToRobotFrame
00119       feet.right.pose.position.z = current_feet.right.pose.position.z+right_foot_shift_z; // adding shift which is eliminated by transformToRobotFrame
00120     }
00121     else
00122       status += ErrorStatusError(msgs::ErrorStatus::ERR_UNKNOWN, "FeetPoseGenerator", "generateFeetPose:  Couldn't determine height of current feet!");
00123   }
00124 
00125   transformToRobotFrame(feet, transform_feet_poses_client);
00126 
00127   return status;
00128 }
00129 
00130 msgs::ErrorStatus FeetPoseGenerator::updateFeetPose(msgs::Feet& feet) const
00131 {
00132   if (!terrain_model || !terrain_model->hasTerrainModel())
00133     return ErrorStatusError(msgs::ErrorStatus::ERR_INVALID_TERRAIN_MODEL, "FeetPoseGenerator", "updateFeetPose: No terrain model available!", false);
00134 
00135   msgs::ErrorStatus status;
00136 
00137   if (!terrain_model->update3DData(feet.left.pose) && !terrain_model->getHeight(feet.left.pose.position.x, feet.left.pose.position.y, feet.left.pose.position.z))
00138     status += ErrorStatusWarning(msgs::ErrorStatus::WARN_UNKNOWN, "FeetPoseGenerator", "updateFeetPose: Couldn't determine either 3D nor height of left foot!", false);
00139 
00140   if (!terrain_model->update3DData(feet.right.pose) && !terrain_model->getHeight(feet.right.pose.position.x, feet.right.pose.position.y, feet.right.pose.position.z))
00141     status += ErrorStatusWarning(msgs::ErrorStatus::WARN_UNKNOWN, "FeetPoseGenerator", "updateFeetPose: Couldn't determine either 3D nor height of right foot!", false);
00142 
00143   return status;
00144 }
00145 
00146 bool FeetPoseGenerator::getCurrentFeetPose(msgs::Feet& feet, const std::string& request_frame)
00147 {
00148   if (tf_listener.canTransform(request_frame, left_foot_frame_id, ros::Time(0)) &&
00149       tf_listener.canTransform(request_frame, right_foot_frame_id, ros::Time(0)))
00150   {
00151     tf::StampedTransform t;
00152     tf_listener.lookupTransform(request_frame, left_foot_frame_id, ros::Time(0), t);
00153     tf::poseTFToMsg(t, feet.left.pose);
00154     feet.left.header.stamp = t.stamp_;
00155     feet.left.foot_index = msgs::Foot::LEFT;
00156 
00157     tf_listener.lookupTransform(request_frame, right_foot_frame_id, ros::Time(0), t);
00158     tf::poseTFToMsg(t, feet.right.pose);
00159     feet.right.header.stamp = t.stamp_;
00160     feet.right.foot_index = msgs::Foot::RIGHT;
00161 
00162     feet.header.stamp = ros::Time::now();
00163     feet.header.frame_id = feet.left.header.frame_id = feet.right.header.frame_id = request_frame;
00164 
00165     return true;
00166   }
00167   return false;
00168 }
00169 
00170 msgs::Feet FeetPoseGenerator::generateFeetPose(const geometry_msgs::PoseStamped& pose)
00171 {
00172   msgs::Feet feet;
00173   double yaw = tf::getYaw(pose.pose.orientation);
00174   double shift_x = -sin(yaw) * (0.5 * foot_separation);
00175   double shift_y =  cos(yaw) * (0.5 * foot_separation);
00176 
00177   feet.header = pose.header;
00178 
00179   feet.left.header = pose.header;
00180   feet.left.foot_index = msgs::Foot::LEFT;
00181   feet.left.pose.position.x = pose.pose.position.x + shift_x;
00182   feet.left.pose.position.y = pose.pose.position.y + shift_y;
00183   feet.left.pose.position.z = pose.pose.position.z;
00184   feet.left.pose.orientation = tf::createQuaternionMsgFromYaw(yaw);
00185 
00186   feet.right.header = pose.header;
00187   feet.right.foot_index = msgs::Foot::RIGHT;
00188   feet.right.pose.position.x = pose.pose.position.x - shift_x;
00189   feet.right.pose.position.y = pose.pose.position.y - shift_y;
00190   feet.right.pose.position.z = pose.pose.position.z;
00191   feet.right.pose.orientation = tf::createQuaternionMsgFromYaw(yaw);
00192 
00193   return feet;
00194 }
00195 
00196 void FeetPoseGenerator::pelvisToGroundTransform(msgs::Feet& feet) const
00197 {
00199   feet.left.pose.position.x += pelvis_to_feet_center.x;
00200   feet.left.pose.position.y += pelvis_to_feet_center.y;
00201   feet.left.pose.position.z += pelvis_to_feet_center.z;
00202 
00203   feet.right.pose.position.x += pelvis_to_feet_center.x;
00204   feet.right.pose.position.y += pelvis_to_feet_center.y;
00205   feet.right.pose.position.z += pelvis_to_feet_center.z;
00206 }
00207 }


vigir_feet_pose_generator
Author(s): Alexander Stumpf
autogenerated on Thu Jun 6 2019 18:37:56