feet_pose_generator.cpp
Go to the documentation of this file.
2 
4 {
6  : has_robot_pose(false)
7 {
8  nh.getParam("foot/separation", foot_separation);
9 
10  nh.getParam("foot/left/frame_id", left_foot_frame_id);
11  nh.getParam("foot/right/frame_id", right_foot_frame_id);
12 
13  nh.getParam("foot/left/foot_frame/z", left_foot_shift_z);
14  nh.getParam("foot/right/foot_frame/z", right_foot_shift_z);
15 
16  // strip '/'
17  strip(left_foot_frame_id, '/');
18  strip(right_foot_frame_id, '/');
19 
20  nh.getParam("pelvis_to_feet_center/x", pelvis_to_feet_center.x);
21  nh.getParam("pelvis_to_feet_center/y", pelvis_to_feet_center.y);
22  nh.getParam("pelvis_to_feet_center/z", pelvis_to_feet_center.z);
23 
24  // start service clients
25  transform_feet_poses_client = nh.serviceClient<msgs::TransformFeetPosesService>("transform_feet_poses");
26 }
27 
29 {
30 }
31 
32 void FeetPoseGenerator::setRobotPose(const geometry_msgs::PoseStampedConstPtr &robot_pose)
33 {
34  this->robot_pose.header = robot_pose->header;
35  this->robot_pose = *robot_pose;
36  has_robot_pose = true;
37 }
38 
39 void FeetPoseGenerator::setRobotPoseWithCovariance(const geometry_msgs::PoseWithCovarianceStampedConstPtr &robot_pose)
40 {
41  this->robot_pose.header = robot_pose->header;
42  this->robot_pose.pose = robot_pose->pose.pose;
43  has_robot_pose = true;
44 }
45 
46 void FeetPoseGenerator::setTerrainModel(const vigir_terrain_classifier::TerrainModelMsg::ConstPtr& terrain_model)
47 {
48  // update terrain model
49  if (this->terrain_model)
50  this->terrain_model->fromMsg(*terrain_model);
51  else
52  this->terrain_model.reset(new vigir_terrain_classifier::TerrainModel(*terrain_model));
53 }
54 
55 msgs::ErrorStatus FeetPoseGenerator::generateFeetPose(const msgs::FeetPoseRequest& request, msgs::Feet& feet)
56 {
57  msgs::ErrorStatus status;
58 
59  // strip '/'
60  std::string request_frame_id = request.header.frame_id;
61  strip(request_frame_id, '/');
62 
63  if (request.flags & msgs::FeetPoseRequest::FLAG_CURRENT)
64  {
65  // try to get current feet pose
66  if (getCurrentFeetPose(feet, request_frame_id))
67  {
68  return status;
69  }
70  // project robot (pelvis) pose to the ground
71  else if (has_robot_pose)
72  {
73  std::string robot_pose_frame_id = strip_const(robot_pose.header.frame_id, '/');
74  if (request_frame_id != robot_pose_frame_id)
75  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!");
76 
78  //pelvisToGroundTransform(feet);
79  }
80  else
81  {
82  return status + ErrorStatusError(msgs::ErrorStatus::ERR_UNKNOWN, "FeetPoseGenerator", "generateFeetPose: No robot pose available for handling FLAG_CURRENT!");
83  }
84  }
85  else
86  {
87  geometry_msgs::PoseStamped pose;
88  pose.header = request.header;
89  pose.pose = request.pose;
90  feet = generateFeetPose(pose);
91  }
92 
93  if (request.flags & msgs::FeetPoseRequest::FLAG_PELVIS_FRAME)
94  {
96  }
97 
98  if (request.flags & msgs::FeetPoseRequest::FLAG_3D)
99  {
100  msgs::ErrorStatus temp_status;
101  msgs::Feet temp_feet = feet;
102 
103  temp_status = updateFeetPose(temp_feet);
104  if (hasError(temp_status))
105  status += ErrorStatusWarning(msgs::ErrorStatus::WARN_UNKNOWN, "FeetPoseGenerator", "generateFeetPose: Couldn't determine either 3D nor height of feet!", false);
106  else
107  {
108  status += temp_status;
109  feet = temp_feet;
110  }
111  }
112 
113  if (request.flags & msgs::FeetPoseRequest::FLAG_CURRENT_Z)
114  {
115  msgs::Feet current_feet;
116  if (getCurrentFeetPose(current_feet, request_frame_id))
117  {
118  feet.left.pose.position.z = current_feet.left.pose.position.z+left_foot_shift_z; // adding shift which is eliminated by transformToRobotFrame
119  feet.right.pose.position.z = current_feet.right.pose.position.z+right_foot_shift_z; // adding shift which is eliminated by transformToRobotFrame
120  }
121  else
122  status += ErrorStatusError(msgs::ErrorStatus::ERR_UNKNOWN, "FeetPoseGenerator", "generateFeetPose: Couldn't determine height of current feet!");
123  }
124 
125  transformToRobotFrame(feet, transform_feet_poses_client);
126 
127  return status;
128 }
129 
130 msgs::ErrorStatus FeetPoseGenerator::updateFeetPose(msgs::Feet& feet) const
131 {
132  if (!terrain_model || !terrain_model->hasTerrainModel())
133  return ErrorStatusError(msgs::ErrorStatus::ERR_INVALID_TERRAIN_MODEL, "FeetPoseGenerator", "updateFeetPose: No terrain model available!", false);
134 
135  msgs::ErrorStatus status;
136 
137  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))
138  status += ErrorStatusWarning(msgs::ErrorStatus::WARN_UNKNOWN, "FeetPoseGenerator", "updateFeetPose: Couldn't determine either 3D nor height of left foot!", false);
139 
140  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))
141  status += ErrorStatusWarning(msgs::ErrorStatus::WARN_UNKNOWN, "FeetPoseGenerator", "updateFeetPose: Couldn't determine either 3D nor height of right foot!", false);
142 
143  return status;
144 }
145 
146 bool FeetPoseGenerator::getCurrentFeetPose(msgs::Feet& feet, const std::string& request_frame)
147 {
148  if (tf_listener.canTransform(request_frame, left_foot_frame_id, ros::Time(0)) &&
150  {
153  tf::poseTFToMsg(t, feet.left.pose);
154  feet.left.header.stamp = t.stamp_;
155  feet.left.foot_index = msgs::Foot::LEFT;
156 
158  tf::poseTFToMsg(t, feet.right.pose);
159  feet.right.header.stamp = t.stamp_;
160  feet.right.foot_index = msgs::Foot::RIGHT;
161 
162  feet.header.stamp = ros::Time::now();
163  feet.header.frame_id = feet.left.header.frame_id = feet.right.header.frame_id = request_frame;
164 
165  return true;
166  }
167  return false;
168 }
169 
170 msgs::Feet FeetPoseGenerator::generateFeetPose(const geometry_msgs::PoseStamped& pose)
171 {
172  msgs::Feet feet;
173  double yaw = tf::getYaw(pose.pose.orientation);
174  double shift_x = -sin(yaw) * (0.5 * foot_separation);
175  double shift_y = cos(yaw) * (0.5 * foot_separation);
176 
177  feet.header = pose.header;
178 
179  feet.left.header = pose.header;
180  feet.left.foot_index = msgs::Foot::LEFT;
181  feet.left.pose.position.x = pose.pose.position.x + shift_x;
182  feet.left.pose.position.y = pose.pose.position.y + shift_y;
183  feet.left.pose.position.z = pose.pose.position.z;
184  feet.left.pose.orientation = tf::createQuaternionMsgFromYaw(yaw);
185 
186  feet.right.header = pose.header;
187  feet.right.foot_index = msgs::Foot::RIGHT;
188  feet.right.pose.position.x = pose.pose.position.x - shift_x;
189  feet.right.pose.position.y = pose.pose.position.y - shift_y;
190  feet.right.pose.position.z = pose.pose.position.z;
191  feet.right.pose.orientation = tf::createQuaternionMsgFromYaw(yaw);
192 
193  return feet;
194 }
195 
196 void FeetPoseGenerator::pelvisToGroundTransform(msgs::Feet& feet) const
197 {
199  feet.left.pose.position.x += pelvis_to_feet_center.x;
200  feet.left.pose.position.y += pelvis_to_feet_center.y;
201  feet.left.pose.position.z += pelvis_to_feet_center.z;
202 
203  feet.right.pose.position.x += pelvis_to_feet_center.x;
204  feet.right.pose.position.y += pelvis_to_feet_center.y;
205  feet.right.pose.position.z += pelvis_to_feet_center.z;
206 }
207 }
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
msgs::ErrorStatus updateFeetPose(msgs::Feet &feet) const
static double getYaw(const Quaternion &bt_q)
void setTerrainModel(const vigir_terrain_classifier::TerrainModelMsg::ConstPtr &terrain_model)
bool canTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, std::string *error_msg=NULL) const
void setRobotPose(const geometry_msgs::PoseStampedConstPtr &robot_pose)
msgs::ErrorStatus generateFeetPose(const msgs::FeetPoseRequest &request, msgs::Feet &feet)
void lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, StampedTransform &transform) const
bool getCurrentFeetPose(msgs::Feet &feet, const std::string &request_frame)
void pelvisToGroundTransform(msgs::Feet &feet) const
static geometry_msgs::Quaternion createQuaternionMsgFromYaw(double yaw)
static void poseTFToMsg(const Pose &bt, geometry_msgs::Pose &msg)
bool getParam(const std::string &key, std::string &s) const
static Time now()
void setRobotPoseWithCovariance(const geometry_msgs::PoseWithCovarianceStampedConstPtr &robot_pose)
vigir_terrain_classifier::TerrainModel::Ptr terrain_model


vigir_feet_pose_generator
Author(s): Alexander Stumpf
autogenerated on Sun Nov 17 2019 03:29:56