00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <xpp_vis/rviz_robot_builder.h>
00031
00032 #include <xpp_states/convert.h>
00033 #include <xpp_vis/rviz_colors.h>
00034
00035 namespace xpp {
00036
00037 RvizRobotBuilder::RvizRobotBuilder()
00038 {
00039 terrain_msg_.friction_coeff = 0.0;
00040 }
00041
00042 void
00043 RvizRobotBuilder::SetRobotParameters (const xpp_msgs::RobotParameters& msg)
00044 {
00045 params_msg_ = msg;
00046 }
00047
00048 void
00049 RvizRobotBuilder::SetTerrainParameters (const xpp_msgs::TerrainInfo& msg)
00050 {
00051 terrain_msg_ = msg;
00052 }
00053
00054 void
00055 RvizRobotBuilder::FillWithInvisible(int max_size, MarkerVec& vec) const
00056 {
00057 Marker invisible = vec.empty()? Marker() : vec.back();
00058 invisible.color.a = 0.0;
00059 vec.resize(max_size, invisible);
00060 }
00061
00062 RvizRobotBuilder::MarkerArray
00063 RvizRobotBuilder::BuildRobotState (const xpp_msgs::RobotStateCartesian& state_msg) const
00064 {
00065 MarkerArray msg;
00066
00067 auto state = Convert::ToXpp(state_msg);
00068 auto ee_pos = state.ee_motion_.Get(kPos);
00069
00070 Marker base = CreateBasePose(state.base_.lin.p_,
00071 state.base_.ang.q,
00072 state.ee_contact_);
00073 msg.markers.push_back(base);
00074
00075 MarkerVec m_ee_pos = CreateEEPositions(ee_pos, state.ee_contact_);
00076 FillWithInvisible(max_ee_, m_ee_pos);
00077 msg.markers.insert(msg.markers.begin(), m_ee_pos.begin(), m_ee_pos.end());
00078
00079 MarkerVec ee_forces = CreateEEForces(state.ee_forces_, ee_pos, state.ee_contact_);
00080 FillWithInvisible(max_ee_, ee_forces);
00081 msg.markers.insert(msg.markers.begin(), ee_forces.begin(), ee_forces.end());
00082
00083 MarkerVec rom = CreateRangeOfMotion(state.base_);
00084 FillWithInvisible(max_ee_, rom);
00085 msg.markers.insert(msg.markers.begin(), rom.begin(), rom.end());
00086
00087 MarkerVec support = CreateSupportArea(state.ee_contact_, ee_pos);
00088 FillWithInvisible(max_ee_, support);
00089 msg.markers.insert(msg.markers.begin(), support.begin(), support.end());
00090
00091 MarkerVec friction = CreateFrictionCones(ee_pos, state.ee_contact_);
00092 FillWithInvisible(max_ee_, friction);
00093 msg.markers.insert(msg.markers.begin(), friction.begin(), friction.end());
00094
00095 Marker cop = CreateCopPos(state.ee_forces_, ee_pos);
00096 msg.markers.push_back(cop);
00097
00098 Marker ip = CreatePendulum(state.base_.lin.p_, state.ee_forces_, ee_pos);
00099 msg.markers.push_back(ip);
00100
00101 msg.markers.push_back(CreateGravityForce(state.base_.lin.p_));
00102
00103 int id = 0;
00104 for (Marker& m : msg.markers) {
00105 m.header.frame_id = frame_id_;
00106 m.id = id++;
00107 }
00108
00109 return msg;
00110 }
00111
00112 RvizRobotBuilder::MarkerVec
00113 RvizRobotBuilder::CreateEEPositions (const EEPos& ee_pos,
00114 const ContactState& in_contact) const
00115 {
00116 MarkerVec vec;
00117
00118 for (auto ee : ee_pos.GetEEsOrdered()) {
00119 Marker m = CreateSphere(ee_pos.at(ee), 0.04);
00120 m.ns = "endeffector_pos";
00121 m.color = color.blue;
00122
00123 vec.push_back(m);
00124 }
00125
00126 return vec;
00127 }
00128
00129 RvizRobotBuilder::Marker
00130 RvizRobotBuilder::CreateGravityForce (const Vector3d& base_pos) const
00131 {
00132 double g = 9.81;
00133 double mass = params_msg_.base_mass;
00134 Marker m = CreateForceArrow(Eigen::Vector3d(0.0, 0.0, -mass*g), base_pos);
00135 m.color = color.red;
00136 m.ns = "gravity_force";
00137
00138 return m;
00139 }
00140
00141 RvizRobotBuilder::MarkerVec
00142 RvizRobotBuilder::CreateEEForces (const EEForces& ee_forces,
00143 const EEPos& ee_pos,
00144 const ContactState& contact_state) const
00145 {
00146 MarkerVec vec;
00147
00148 for (auto ee : ee_forces.GetEEsOrdered()) {
00149 Vector3d p = ee_pos.at(ee);
00150 Vector3d f = ee_forces.at(ee);
00151
00152 Marker m = CreateForceArrow(f, p);
00153 m.color = color.red;
00154 m.color.a = f.norm() > 0.1 ? 1.0 : 0.0;
00155 m.ns = "ee_force";
00156 vec.push_back(m);
00157 }
00158
00159 return vec;
00160 }
00161
00162 RvizRobotBuilder::MarkerVec
00163 RvizRobotBuilder::CreateFrictionCones (const EEPos& ee_pos,
00164 const ContactState& contact_state) const
00165 {
00166 MarkerVec vec;
00167
00168
00169 Marker invisible = CreateFrictionCone(Vector3d::Zero(), Vector3d::Zero(), 0.0);
00170 invisible.color.a = 0.0;
00171 vec.push_back(invisible);
00172
00173
00174 double mu = terrain_msg_.friction_coeff;
00175 if (ee_pos.GetEECount() == terrain_msg_.surface_normals.size() && mu > 1e-3) {
00176
00177 auto normals = Convert::ToXpp(terrain_msg_.surface_normals);
00178 for (auto ee : normals.GetEEsOrdered()) {
00179 Marker m;
00180 Vector3d n = normals.at(ee);
00181 m = CreateFrictionCone(ee_pos.at(ee), -n, mu);
00182 m.color = color.red;
00183 m.color.a = contact_state.at(ee)? 0.25 : 0.0;
00184 vec.push_back(m);
00185 }
00186 }
00187
00188 return vec;
00189 }
00190
00191 RvizRobotBuilder::Marker
00192 RvizRobotBuilder::CreateFrictionCone (const Vector3d& pos,
00193 const Vector3d& normal,
00194 double mu) const
00195 {
00196 Marker m;
00197 m.type = Marker::ARROW;
00198 m.ns = "friction_cone";
00199
00200 double cone_height = 0.1;
00201
00202 m.scale.x = 0.00;
00203 m.scale.y = 2.0 * cone_height * mu;
00204 m.scale.z = cone_height;
00205
00206 auto start = Convert::ToRos<geometry_msgs::Point>(pos + normal);
00207 m.points.push_back(start);
00208
00209 auto end = Convert::ToRos<geometry_msgs::Point>(pos);
00210 m.points.push_back(end);
00211
00212 return m;
00213 }
00214
00215 RvizRobotBuilder::Marker
00216 RvizRobotBuilder::CreateBasePose (const Vector3d& pos,
00217 Eigen::Quaterniond ori,
00218 const ContactState& contact_state) const
00219 {
00220 Vector3d edge_length(0.1, 0.05, 0.02);
00221 Marker m = CreateBox(pos, ori, 3*edge_length);
00222
00223 m.color = color.black;
00224 m.color.a = 0.8;
00225 for (auto ee : contact_state.GetEEsOrdered())
00226 if (contact_state.at(ee))
00227 m.color = color.black;
00228
00229 m.ns = "base_pose";
00230
00231 return m;
00232 }
00233
00234 RvizRobotBuilder::Marker
00235 RvizRobotBuilder::CreateCopPos (const EEForces& ee_forces,
00236 const EEPos& ee_pos) const
00237 {
00238 double z_sum = 0.0;
00239 for (Vector3d ee : ee_forces.ToImpl())
00240 z_sum += ee.z();
00241
00242 Marker m;
00243
00244 Vector3d cop = Vector3d::Zero();
00245 if (z_sum > 0.0) {
00246 for (auto ee : ee_forces.GetEEsOrdered()) {
00247 double p = ee_forces.at(ee).z()/z_sum;
00248 cop += p*ee_pos.at(ee);
00249 }
00250 m = CreateSphere(cop);
00251 } else {
00252 m = CreateSphere(cop, 0.001);
00253 }
00254
00255 m.color = color.red;
00256 m.ns = "cop";
00257
00258 return m;
00259 }
00260
00261 RvizRobotBuilder::Marker
00262 RvizRobotBuilder::CreatePendulum (const Vector3d& pos,
00263 const EEForces& ee_forces,
00264 const EEPos& ee_pos) const
00265 {
00266 Marker m;
00267 m.type = Marker::LINE_STRIP;
00268 m.scale.x = 0.007;
00269
00270 geometry_msgs::Point cop = CreateCopPos(ee_forces, ee_pos).pose.position;
00271 geometry_msgs::Point com = CreateSphere(pos).pose.position;
00272
00273 m.points.push_back(cop);
00274 m.points.push_back(com);
00275
00276 m.ns = "inverted_pendulum";
00277 m.color = color.black;
00278
00279 double fz_sum = 0.0;
00280 for (Vector3d ee : ee_forces.ToImpl())
00281 fz_sum += ee.z();
00282
00283 if (fz_sum < 1.0)
00284 m.color.a = 0.0;
00285
00286 return m;
00287 }
00288
00289 RvizRobotBuilder::MarkerVec
00290 RvizRobotBuilder::CreateRangeOfMotion (const State3d& base) const
00291 {
00292 MarkerVec vec;
00293
00294 auto w_R_b = base.ang.q.toRotationMatrix();
00295
00296 for (const auto& pos_B : params_msg_.nominal_ee_pos) {
00297 Vector3d pos_W = base.lin.p_ + w_R_b*Convert::ToXpp(pos_B);
00298
00299 Vector3d edge_length = 2*Convert::ToXpp(params_msg_.ee_max_dev);
00300 Marker m = CreateBox(pos_W, base.ang.q, edge_length);
00301 m.color = color.blue;
00302 m.color.a = 0.2;
00303 m.ns = "range_of_motion";
00304 vec.push_back(m);
00305 }
00306
00307 return vec;
00308 }
00309
00310 RvizRobotBuilder::Marker
00311 RvizRobotBuilder::CreateBox (const Vector3d& pos, Eigen::Quaterniond ori,
00312 const Vector3d& edge_length) const
00313 {
00314 Marker m;
00315
00316 m.type = Marker::CUBE;
00317 m.pose.position = Convert::ToRos<geometry_msgs::Point>(pos);
00318 m.pose.orientation = Convert::ToRos(ori);
00319 m.scale = Convert::ToRos<geometry_msgs::Vector3>(edge_length);
00320
00321 return m;
00322 }
00323
00324 RvizRobotBuilder::Marker
00325 RvizRobotBuilder::CreateSphere (const Vector3d& pos, double diameter) const
00326 {
00327 Marker m;
00328
00329 m.type = Marker::SPHERE;
00330 m.pose.position = Convert::ToRos<geometry_msgs::Point>(pos);
00331 m.scale.x = diameter;
00332 m.scale.y = diameter;
00333 m.scale.z = diameter;
00334
00335 return m;
00336 }
00337
00338 RvizRobotBuilder::Marker
00339 RvizRobotBuilder::CreateForceArrow (const Vector3d& force,
00340 const Vector3d& ee_pos) const
00341 {
00342 Marker m;
00343 m.type = Marker::ARROW;
00344
00345 m.scale.x = 0.01;
00346 m.scale.y = 0.02;
00347 m.scale.z = 0.06;
00348
00349 double force_scale = 800;
00350 Vector3d p_start = ee_pos - force/force_scale;
00351 auto start = Convert::ToRos<geometry_msgs::Point>(p_start);
00352 m.points.push_back(start);
00353
00354 auto end = Convert::ToRos<geometry_msgs::Point>(ee_pos);
00355 m.points.push_back(end);
00356
00357 return m;
00358 }
00359
00360 RvizRobotBuilder::MarkerVec
00361 RvizRobotBuilder::CreateSupportArea (const ContactState& contact_state,
00362 const EEPos& ee_pos) const
00363 {
00364 MarkerVec vec;
00365
00366 Marker m;
00367 m.ns = "support_polygons";
00368 m.scale.x = m.scale.y = m.scale.z = 1.0;
00369
00370 for (auto ee : contact_state.GetEEsOrdered()) {
00371 if (contact_state.at(ee)) {
00372 auto p = Convert::ToRos<geometry_msgs::Point>(ee_pos.at(ee));
00373 m.points.push_back(p);
00374 m.color = color.black;
00375 m.color.a = 0.2;
00376 }
00377 }
00378
00379 switch (m.points.size()) {
00380 case 4: {
00381 m.type = Marker::TRIANGLE_LIST;
00382 auto temp = m.points;
00383
00384
00385 m.points.pop_back();
00386 vec.push_back(m);
00387
00388 m.points = temp;
00389 m.points.erase(m.points.begin());
00390 vec.push_back(m);
00391 break;
00392 }
00393 case 3: {
00394 m.type = Marker::TRIANGLE_LIST;
00395 vec.push_back(m);
00396 vec.push_back(m);
00397 break;
00398 }
00399 case 2: {
00400 m.type = Marker::LINE_STRIP;
00401 m.scale.x = 0.01;
00402 vec.push_back(m);
00403 vec.push_back(m);
00404 break;
00405 }
00406 case 1: {
00407
00408 m.type = Marker::CUBE;
00409 m.color.a = 0.0;
00410 vec.push_back(m);
00411 vec.push_back(m);
00412 break;
00413 }
00414 default:
00415 m.type = Marker::CUBE;
00416 m.color.a = 0.0;
00417 vec.push_back(m);
00418 vec.push_back(m);
00419 break;
00420 }
00421
00422 return vec;
00423 }
00424
00425 }