$search
00001 /****************************************************************************** 00002 * \file 00003 * 00004 * $Id: Primitive.cpp 676 2012-04-19 18:32:07Z xlokaj03 $ 00005 * 00006 * Copyright (C) Brno University of Technology 00007 * 00008 * This file is part of software developed by Robo@FIT group. 00009 * 00010 * Author: Tomas Lokaj (xlokaj03@stud.fit.vutbr.cz) 00011 * Supervised by: Michal Spanel (spanel@fit.vutbr.cz) 00012 * Date: 24/11/2011 00013 * 00014 * This file is free software: you can redistribute it and/or modify 00015 * it under the terms of the GNU Lesser General Public License as published by 00016 * the Free Software Foundation, either version 3 of the License, or 00017 * (at your option) any later version. 00018 * 00019 * This file is distributed in the hope that it will be useful, 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 * GNU Lesser General Public License for more details. 00023 * 00024 * You should have received a copy of the GNU Lesser General Public License 00025 * along with this file. If not, see <http://www.gnu.org/licenses/>. 00026 */ 00027 00028 #include <srs_interaction_primitives/primitive.h> 00029 00030 using namespace std; 00031 using namespace interactive_markers; 00032 using namespace visualization_msgs; 00033 using namespace geometry_msgs; 00034 using namespace std_msgs; 00035 00036 namespace srs_interaction_primitives 00037 { 00038 00039 Primitive::Primitive(InteractiveMarkerServerPtr server, string frame_id, string name, int type) 00040 { 00041 server_ = server; 00042 frame_id_ = frame_id; 00043 name_ = name; 00044 primitive_type_ = type; 00045 menu_created_ = false; 00046 pose_type_ = PoseType::POSE_CENTER; 00047 00048 show_movement_control_ = show_scale_control_ = show_rotation_control_ = show_measure_control_ = 00049 show_description_control_ = show_trajectory_control_ = false; 00050 00051 updatePublisher_ = new UpdatePublisher(name_, primitive_type_); 00052 color_green_a01_.r = 0.0; 00053 color_green_a01_.g = 1.0; 00054 color_green_a01_.b = 0.0; 00055 color_green_a01_.a = 0.1; 00056 00057 scale_saved_ = 0; 00058 } 00059 00060 void Primitive::defaultCallback(const InteractiveMarkerFeedbackConstPtr &feedback) 00061 { 00062 // Update the scale marker positions 00063 if( scale_saved_ > 1 ) 00064 { 00065 Vector3 scale_change; 00066 scale_change.x = scale_.x - scale_prev_.x; 00067 scale_change.y = scale_.y - scale_prev_.y; 00068 scale_change.z = scale_.z - scale_prev_.z; 00069 scale_saved_ = 0; 00070 00071 updatePublisher_->publishScaleChanged(scale_, scale_change); 00072 00073 removeScaleControls(); 00074 addScaleControls(); 00075 00076 server_->applyChanges(); 00077 } 00078 00079 // Process the feedback 00080 if (feedback->event_type == InteractiveMarkerFeedback::MOUSE_UP) 00081 { 00082 geometry_msgs::Pose npose = feedback->pose; 00083 if (frame_id_ != feedback->header.frame_id) 00084 { 00085 //ROS_INFO("Different frame ids"); 00086 try 00087 { 00088 tfListener = new tf::TransformListener(); 00089 tfListener->waitForTransform(feedback->header.frame_id, frame_id_, feedback->header.stamp, ros::Duration(2.0)); 00090 tfListener->lookupTransform(feedback->header.frame_id, frame_id_, feedback->header.stamp, feedbackToDefaultTransform); 00091 delete tfListener; 00092 transformer.setTransform(feedbackToDefaultTransform); 00093 00094 btVector3 position; 00095 position.setX(feedback->pose.position.x); 00096 position.setY(feedback->pose.position.y); 00097 position.setZ(feedback->pose.position.z); 00098 00099 btQuaternion orientation; 00100 orientation.setX(feedback->pose.orientation.x); 00101 orientation.setY(feedback->pose.orientation.y); 00102 orientation.setZ(feedback->pose.orientation.z); 00103 orientation.setW(feedback->pose.orientation.w); 00104 00105 tf::Stamped<btTransform> pose; 00106 pose.setOrigin(position); 00107 pose.setRotation(orientation); 00108 pose.frame_id_ = feedback->header.frame_id; 00109 transformer.transformPose(frame_id_, pose, pose); 00110 00111 npose.position.x = pose.getOrigin().getX(); 00112 npose.position.y = pose.getOrigin().getY(); 00113 npose.position.z = pose.getOrigin().getZ(); 00114 npose.orientation.x = pose.getRotation().getX(); 00115 npose.orientation.y = pose.getRotation().getY(); 00116 npose.orientation.z = pose.getRotation().getZ(); 00117 npose.orientation.w = pose.getRotation().getW(); 00118 } 00119 catch (tf::TransformException& ex) 00120 { 00121 ROS_WARN("Transform error!"); 00122 delete tfListener; 00123 return; 00124 } 00125 } 00126 00127 // Calculate the pose change in the frame_id_ 00128 pose_change.position = npose.position; 00129 pose_change.position.x -= pose_.position.x; 00130 pose_change.position.y -= pose_.position.y; 00131 pose_change.position.z -= pose_.position.z; 00132 00133 btQuaternion orientation(pose_.orientation.x, 00134 pose_.orientation.y, 00135 pose_.orientation.z, 00136 pose_.orientation.w); 00137 orientation.inverse(); 00138 orientation *= btQuaternion(npose.orientation.x, 00139 npose.orientation.y, 00140 npose.orientation.z, 00141 npose.orientation.w); 00142 00143 pose_change.orientation.x = orientation.getX(); 00144 pose_change.orientation.y = orientation.getY(); 00145 pose_change.orientation.z = orientation.getZ(); 00146 pose_change.orientation.w = orientation.getW(); 00147 00148 // Store the new position 00149 pose_ = npose; 00150 00151 insert(); 00152 server_->applyChanges(); 00153 00154 // Majkl: Why the pose changed was published in the message frame ID and not in the IM's one? 00155 // updatePublisher_->publishPoseChanged(feedback->pose, pose_change); 00156 updatePublisher_->publishPoseChanged(pose_, pose_change); 00157 } 00158 } 00159 00160 void Primitive::scaleFeedback(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback) 00161 { 00162 btVector3 center(pose_.position.x, pose_.position.y, pose_.position.z); 00163 btQuaternion orient(pose_.orientation.x, pose_.orientation.y, pose_.orientation.z, pose_.orientation.w); 00164 00165 if (feedback->event_type == InteractiveMarkerFeedback::MOUSE_DOWN) 00166 { 00167 scale_prev_.x = scale_.x; 00168 scale_prev_.y = scale_.y; 00169 scale_prev_.z = scale_.z; 00170 scale_saved_ = 1; 00171 } 00172 else if (feedback->event_type == InteractiveMarkerFeedback::MOUSE_UP && scale_saved_ > 0) 00173 { 00174 Vector3 scale_change; 00175 scale_change.x = scale_.x - scale_prev_.x; 00176 scale_change.y = scale_.y - scale_prev_.y; 00177 scale_change.z = scale_.z - scale_prev_.z; 00178 scale_saved_ = 0; 00179 00180 updatePublisher_->publishScaleChanged(scale_, scale_change); 00181 00182 removeScaleControls(); 00183 addScaleControls(); 00184 00185 server_->applyChanges(); 00186 } 00187 else if (feedback->event_type == InteractiveMarkerFeedback::POSE_UPDATE && scale_saved_ > 0) 00188 { 00189 ++scale_saved_; 00190 00191 geometry_msgs::Pose npose = feedback->pose; 00192 if( frame_id_ != feedback->header.frame_id ) 00193 { 00194 // ROS_INFO("different frame"); 00195 try 00196 { 00197 tfListener = new tf::TransformListener(); 00198 tfListener->waitForTransform(feedback->header.frame_id, frame_id_, feedback->header.stamp, ros::Duration(2.0)); 00199 tfListener->lookupTransform(feedback->header.frame_id, frame_id_, feedback->header.stamp, feedbackToDefaultTransform); 00200 delete tfListener; 00201 transformer.setTransform(feedbackToDefaultTransform); 00202 00203 btVector3 position; 00204 position.setX(feedback->pose.position.x); 00205 position.setY(feedback->pose.position.y); 00206 position.setZ(feedback->pose.position.z); 00207 00208 btQuaternion orientation; 00209 orientation.setX(feedback->pose.orientation.x); 00210 orientation.setY(feedback->pose.orientation.y); 00211 orientation.setZ(feedback->pose.orientation.z); 00212 orientation.setW(feedback->pose.orientation.w); 00213 00214 tf::Stamped<btTransform> pose; 00215 pose.setOrigin(position); 00216 pose.setRotation(orientation); 00217 pose.frame_id_ = feedback->header.frame_id; 00218 transformer.transformPose(frame_id_, pose, pose); 00219 00220 npose.position.x = pose.getOrigin().getX(); 00221 npose.position.y = pose.getOrigin().getY(); 00222 npose.position.z = pose.getOrigin().getZ(); 00223 npose.orientation.x = pose.getRotation().getX(); 00224 npose.orientation.y = pose.getRotation().getY(); 00225 npose.orientation.z = pose.getRotation().getZ(); 00226 npose.orientation.w = pose.getRotation().getW(); 00227 } 00228 catch (tf::TransformException& ex) 00229 { 00230 ROS_WARN("Transform error!"); 00231 delete tfListener; 00232 return; 00233 } 00234 } 00235 00236 btVector3 position(npose.position.x, npose.position.y, npose.position.z); 00237 btVector3 vec = position - center; 00238 double size = vec.length(); 00239 00240 btVector3 rotated = quatRotate(orient, btVector3(1, 0, 0)); 00241 int xsign = 1; 00242 if( rotated.x() < 0 ) 00243 { 00244 xsign = -1; 00245 } 00246 rotated = quatRotate(orient, btVector3(0, 1, 0)); 00247 int ysign = 1; 00248 if( rotated.y() < 0 ) 00249 { 00250 ysign = -1; 00251 } 00252 rotated = quatRotate(orient, btVector3(0, 0, 1)); 00253 int zsign = 1; 00254 if( rotated.z() < 0 ) 00255 { 00256 zsign = -1; 00257 } 00258 00259 if (feedback->marker_name == name_ + "_min_x") 00260 { 00261 int sign = (pose_.position.x - npose.position.x) > 0.0 ? 1 : -1; 00262 scale_.x = scale_prev_.x + xsign * sign * size; 00263 // scale_.x = scale_prev_.x + xsign * (pose_.position.x - npose.position.x); 00264 } 00265 else if (feedback->marker_name == name_ + "_max_x") 00266 { 00267 int sign = (npose.position.x - pose_.position.x) > 0.0 ? 1 : -1; 00268 scale_.x = scale_prev_.x + xsign * sign * size; 00269 // scale_.x = scale_prev_.x + xsign * (npose.position.x - pose_.position.x); 00270 } 00271 else if (feedback->marker_name == name_ + "_min_y") 00272 { 00273 int sign = (pose_.position.y - npose.position.y) > 0.0 ? 1 : -1; 00274 scale_.y = scale_prev_.y + ysign * sign * size; 00275 // scale_.y = scale_prev_.y + ysign * (pose_.position.y - npose.position.y); 00276 } 00277 else if (feedback->marker_name == name_ + "_max_y") 00278 { 00279 int sign = (npose.position.y - pose_.position.y) > 0.0 ? 1 : -1; 00280 scale_.y = scale_prev_.y + ysign * sign * size; 00281 // scale_.y = scale_prev_.y + ysign * (npose.position.y - pose_.position.y); 00282 } 00283 else if (feedback->marker_name == name_ + "_min_z") 00284 { 00285 int sign = (pose_.position.z - npose.position.z) > 0.0 ? 1 : -1; 00286 scale_.z = scale_prev_.z + zsign * sign * size; 00287 // scale_.z = scale_prev_.z + zsign * (pose_.position.z - npose.position.z); 00288 } 00289 else if (feedback->marker_name == name_ + "_max_z") 00290 { 00291 int sign = (npose.position.z - pose_.position.z) > 0.0 ? 1 : -1; 00292 scale_.z = scale_prev_.z + zsign * sign * size; 00293 // scale_.z = scale_prev_.z + zsign * (npose.position.z - pose_.position.z); 00294 } 00295 00296 if (scale_.x < 0.0) scale_.x = 0.001; 00297 if (scale_.y < 0.0) scale_.y = 0.001; 00298 if (scale_.z < 0.0) scale_.z = 0.001; 00299 00300 if ((object_.controls.size() > 0) && (object_.controls[0].markers.size() > 0)) 00301 { 00302 object_.controls[0].markers[0].scale = scale_; 00303 } 00304 object_.scale = srs_interaction_primitives::maxScale(scale_); 00305 00306 updateControls(); 00307 00308 insert(); 00309 server_->applyChanges(); 00310 } 00311 } 00312 00313 InteractiveMarkerControl* Primitive::getControl(string name) 00314 { 00315 for (unsigned int i = 0; i < object_.controls.size(); i++) 00316 { 00317 if (object_.controls[i].name == name) 00318 return (&object_.controls.at(i)); 00319 } 00320 return NULL; 00321 } 00322 00323 void Primitive::insert() 00324 { 00325 server_->insert(object_); 00326 } 00327 00328 void Primitive::erase() 00329 { 00330 server_->erase(name_); 00331 00332 // Scale controls are managed as separate interactive markers... 00333 removeScaleControls(); 00334 } 00335 00336 void Primitive::addMovementControls() 00337 { 00338 show_movement_control_ = true; 00339 00340 moveXControl_.name = "move_x"; 00341 // moveXControl_.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, 0, 0); 00342 moveXControl_.orientation.w = 1; 00343 moveXControl_.orientation.x = 1; 00344 moveXControl_.orientation.y = 0; 00345 moveXControl_.orientation.z = 0; 00346 moveXControl_.interaction_mode = InteractiveMarkerControl::MOVE_AXIS; 00347 00348 moveYControl_.name = "move_y"; 00349 // moveYControl_.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, 0, 0.5 * M_PI); 00350 moveYControl_.orientation.w = 1; 00351 moveYControl_.orientation.x = 0; 00352 moveYControl_.orientation.y = 0; 00353 moveYControl_.orientation.z = 1; 00354 moveYControl_.interaction_mode = InteractiveMarkerControl::MOVE_AXIS; 00355 00356 moveZControl_.name = "move_z"; 00357 // moveZControl_.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, -0.5 * M_PI, 0); 00358 moveZControl_.orientation.w = 1; 00359 moveZControl_.orientation.x = 0; 00360 moveZControl_.orientation.y = 1; 00361 moveZControl_.orientation.z = 0; 00362 moveZControl_.interaction_mode = InteractiveMarkerControl::MOVE_AXIS; 00363 00364 object_.controls.push_back(moveXControl_); 00365 object_.controls.push_back(moveYControl_); 00366 object_.controls.push_back(moveZControl_); 00367 } 00368 00369 void Primitive::addRotationControls() 00370 { 00371 show_rotation_control_ = true; 00372 00373 rotateXControl_.name = "rotate_x"; 00374 // rotateXControl_.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, 0, 0); 00375 rotateXControl_.orientation.w = 1; 00376 rotateXControl_.orientation.x = 1; 00377 rotateXControl_.orientation.y = 0; 00378 rotateXControl_.orientation.z = 0; 00379 rotateXControl_.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS; 00380 00381 rotateYControl.name = "rotate_y"; 00382 // rotateYControl.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, 0, 0.5 * M_PI); 00383 rotateYControl.orientation.w = 1; 00384 rotateYControl.orientation.x = 0; 00385 rotateYControl.orientation.y = 0; 00386 rotateYControl.orientation.z = 1; 00387 rotateYControl.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS; 00388 00389 rotateZControl_.name = "rotate_z"; 00390 // moveZControl_.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, -0.5 * M_PI, 0); 00391 rotateZControl_.orientation.w = 1; 00392 rotateZControl_.orientation.x = 0; 00393 rotateZControl_.orientation.y = 1; 00394 rotateZControl_.orientation.z = 0; 00395 rotateZControl_.interaction_mode = InteractiveMarkerControl::ROTATE_AXIS; 00396 00397 object_.controls.push_back(rotateXControl_); 00398 object_.controls.push_back(rotateYControl); 00399 object_.controls.push_back(rotateZControl_); 00400 } 00401 00402 void Primitive::removeMovementControls() 00403 { 00404 show_movement_control_ = false; 00405 removeControl("move_x"); 00406 removeControl("move_y"); 00407 removeControl("move_z"); 00408 } 00409 00410 void Primitive::removeRotationControls() 00411 { 00412 show_rotation_control_ = false; 00413 removeControl("rotate_x"); 00414 removeControl("rotate_y"); 00415 removeControl("rotate_z"); 00416 } 00417 00418 void Primitive::removeControl(string name) 00419 { 00420 ROS_WARN("REMOVING %s", name.c_str()); 00421 for (unsigned int i = 0; i < object_.controls.size(); i++) 00422 { 00423 std::cout << object_.controls[i].name << std::endl; 00424 if (object_.controls[i].name == name) 00425 { 00426 ROS_WARN("OK"); 00427 object_.controls.erase(object_.controls.begin() + i); 00428 return; 00429 } 00430 } 00431 } 00432 00433 void Primitive::addMeasureControl() 00434 { 00435 show_measure_control_ = true; 00436 00437 Marker measureMarker; 00438 measureControl_.markers.clear(); 00439 measureMarker.type = Marker::LINE_LIST; 00440 measureMarker.color.r = color_.g; 00441 measureMarker.color.g = color_.b; 00442 measureMarker.color.b = color_.r; 00443 measureMarker.color.a = 1.0; 00444 measureMarker.scale.x = 0.01; 00445 Point p; 00446 // Z 00447 double sx = scale_.x / 2; 00448 double sy = scale_.y / 2; 00449 double sz = scale_.z / 2; 00450 p.x = -sx; 00451 p.y = -sy; 00452 p.z = -sz; 00453 measureMarker.points.push_back(p); 00454 p.z = sz; 00455 measureMarker.points.push_back(p); 00456 // Y 00457 p.x = -sx; 00458 p.y = sy; 00459 p.z = -sz; 00460 measureMarker.points.push_back(p); 00461 p.y = -sy; 00462 measureMarker.points.push_back(p); 00463 // X 00464 p.x = sx; 00465 p.y = -sy; 00466 p.z = -sz; 00467 measureMarker.points.push_back(p); 00468 p.x = -sx; 00469 measureMarker.points.push_back(p); 00470 00471 Marker measureText; 00472 ostringstream text_x, text_y, text_z; 00473 text_x << setprecision(2) << fixed << scale_.x << "m"; 00474 text_y << setprecision(2) << fixed << scale_.y << "m"; 00475 text_z << setprecision(2) << fixed << scale_.z << "m"; 00476 measureText.type = Marker::TEXT_VIEW_FACING; 00477 measureText.color = measureMarker.color; 00478 // Z 00479 measureText.scale.z = scale_.z * MEASURE_TEXT_SCALE; 00480 if (measureText.scale.z > MEASURE_TEXT_MAX_SIZE) 00481 measureText.scale.z = MEASURE_TEXT_MAX_SIZE; 00482 else if (measureText.scale.z < MEASURE_TEXT_MIN_SIZE) 00483 measureText.scale.z = MEASURE_TEXT_MIN_SIZE; 00484 measureText.pose.position.x = -sx - 0.2; 00485 measureText.pose.position.y = -sy - 0.2; 00486 measureText.pose.position.z = 0; 00487 measureText.text = text_z.str(); 00488 measureControl_.markers.push_back(measureText); 00489 // Y 00490 measureText.scale.z = scale_.y * MEASURE_TEXT_SCALE; 00491 if (measureText.scale.z > MEASURE_TEXT_MAX_SIZE) 00492 measureText.scale.z = MEASURE_TEXT_MAX_SIZE; 00493 else if (measureText.scale.z < MEASURE_TEXT_MIN_SIZE) 00494 measureText.scale.z = MEASURE_TEXT_MIN_SIZE; 00495 measureText.pose.position.x = -sx - 0.2; 00496 measureText.pose.position.y = 0; 00497 measureText.pose.position.z = -sz - 0.2; 00498 measureText.text = text_y.str(); 00499 measureControl_.markers.push_back(measureText); 00500 // X 00501 measureText.scale.z = scale_.x * MEASURE_TEXT_SCALE; 00502 if (measureText.scale.z > MEASURE_TEXT_MAX_SIZE) 00503 measureText.scale.z = MEASURE_TEXT_MAX_SIZE; 00504 else if (measureText.scale.z < MEASURE_TEXT_MIN_SIZE) 00505 measureText.scale.z = MEASURE_TEXT_MIN_SIZE; 00506 measureText.pose.position.x = 0; 00507 measureText.pose.position.y = -sy - 0.2; 00508 measureText.pose.position.z = -sz - 0.2; 00509 measureText.text = text_x.str(); 00510 measureControl_.markers.push_back(measureText); 00511 00512 measureControl_.name = "measure_control"; 00513 measureControl_.markers.push_back(measureMarker); 00514 measureControl_.interaction_mode = InteractiveMarkerControl::NONE; 00515 measureControl_.always_visible = true; 00516 00517 object_.controls.push_back(measureControl_); 00518 } 00519 00520 void Primitive::removeMeasureControl() 00521 { 00522 show_measure_control_ = false; 00523 removeControl("measure_control"); 00524 } 00525 00526 void Primitive::removeDescriptionControl() 00527 { 00528 show_description_control_ = false; 00529 removeControl("description_control"); 00530 } 00531 00532 void Primitive::addDescriptionControl() 00533 { 00534 show_description_control_ = true; 00535 00536 descriptionControl_.markers.clear(); 00537 00538 Marker descriptionMarker; 00539 descriptionMarker.type = Marker::TEXT_VIEW_FACING; 00540 descriptionMarker.text = description_; 00541 // descriptionMarker.scale.z = 0.2; 00542 // descriptionMarker.color.r = color_.b; 00543 // descriptionMarker.color.g = color_.r; 00544 // descriptionMarker.color.b = color_.g; 00545 // descriptionMarker.pose.position.z = object_.scale / 2 + 0.2; 00546 descriptionMarker.scale.z = object_.scale * 0.2; 00547 descriptionMarker.color.r = 1.0; 00548 descriptionMarker.color.g = 1.0; 00549 descriptionMarker.color.b = 1.0; 00550 descriptionMarker.color.a = 1.0; 00551 descriptionMarker.pose.position.z = object_.scale * 0.8 + 0.2; 00552 00553 descriptionControl_.name = "description_control"; 00554 descriptionControl_.markers.push_back(descriptionMarker); 00555 descriptionControl_.interaction_mode = InteractiveMarkerControl::NONE; 00556 descriptionControl_.orientation_mode = InteractiveMarkerControl::FIXED; 00557 descriptionControl_.always_visible = true; 00558 00559 object_.controls.push_back(descriptionControl_); 00560 } 00561 00562 void Primitive::removeScaleControls() 00563 { 00564 show_scale_control_ = false; 00565 server_->erase(name_ + "_max_x"); 00566 server_->erase(name_ + "_max_y"); 00567 server_->erase(name_ + "_max_z"); 00568 server_->erase(name_ + "_min_x"); 00569 server_->erase(name_ + "_min_y"); 00570 server_->erase(name_ + "_min_z"); 00571 } 00572 00573 void Primitive::addScaleControls() 00574 { 00575 show_scale_control_ = true; 00576 00577 min_size_.x = pose_.position.x - scale_.x * 0.5; 00578 max_size_.x = pose_.position.x + scale_.x * 0.5; 00579 min_size_.y = pose_.position.y - scale_.y * 0.5; 00580 max_size_.y = pose_.position.y + scale_.y * 0.5; 00581 min_size_.z = pose_.position.z - scale_.z * 0.5; 00582 max_size_.z = pose_.position.z + scale_.z * 0.5; 00583 00584 for (int axis = 0; axis < 3; axis++) 00585 { 00586 for (int sign = -1; sign <= 1; sign += 2) 00587 { 00588 InteractiveMarker int_marker; 00589 int_marker.header.frame_id = frame_id_; 00590 // int_marker.scale = 1.0; 00591 int_marker.scale = 0.6 * srs_interaction_primitives::maxScale(scale_); 00592 int_marker.pose = pose_; 00593 00594 InteractiveMarkerControl control; 00595 control.interaction_mode = InteractiveMarkerControl::MOVE_AXIS; 00596 control.orientation_mode = InteractiveMarkerControl::INHERIT; 00597 control.always_visible = false; 00598 00599 switch (axis) 00600 { 00601 case 0: 00602 int_marker.name = sign > 0 ? name_ + "_max_x" : name_ + "_min_x"; 00603 // control.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, 0, 0); 00604 control.orientation.w = 1; 00605 control.orientation.x = 1; 00606 control.orientation.y = 0; 00607 control.orientation.z = 0; 00608 break; 00609 case 1: 00610 int_marker.name = sign > 0 ? name_ + "_max_y" : name_ + "_min_y"; 00611 // control.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, 0, 0.5 * M_PI); 00612 control.orientation.w = 1; 00613 control.orientation.x = 0; 00614 control.orientation.y = 0; 00615 control.orientation.z = 1; 00616 break; 00617 default: 00618 // int_marker.name = sign > 0 ? name_ + "_max_z" : name_ + "_min_z"; 00619 int_marker.name = sign < 0 ? name_ + "_max_z" : name_ + "_min_z"; 00620 // control.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, -0.5 * M_PI, 0); 00621 control.orientation.w = 1; 00622 control.orientation.x = 0; 00623 control.orientation.y = 1; 00624 control.orientation.z = 0; 00625 break; 00626 } 00627 00628 makeArrow(int_marker, control, 3.0 * sign); 00629 // makeArrow(int_marker, control, 3.5 * sign); 00630 00631 int_marker.controls.push_back(control); 00632 server_->insert(int_marker, boost::bind(&Primitive::scaleFeedback, this, _1)); 00633 } 00634 } 00635 } 00636 00637 void Primitive::updateScaleControls() 00638 { 00639 min_size_.x = pose_.position.x - scale_.x * 0.5; 00640 max_size_.x = pose_.position.x + scale_.x * 0.5; 00641 min_size_.y = pose_.position.y - scale_.y * 0.5; 00642 max_size_.y = pose_.position.y + scale_.y * 0.5; 00643 min_size_.z = pose_.position.z - scale_.z * 0.5; 00644 max_size_.z = pose_.position.z + scale_.z * 0.5; 00645 00646 for (int axis = 0; axis < 3; axis++) 00647 { 00648 for (int sign = -1; sign <= 1; sign += 2) 00649 { 00650 string n; 00651 switch (axis) 00652 { 00653 case 0: 00654 n = sign > 0 ? name_ + "_max_x" : name_ + "_min_x"; 00655 break; 00656 case 1: 00657 n = sign > 0 ? name_ + "_max_y" : name_ + "_min_y"; 00658 break; 00659 default: 00660 n = sign > 0 ? name_ + "_max_z" : name_ + "_min_z"; 00661 break; 00662 } 00663 server_->setPose(n, pose_); 00664 server_->applyChanges(); 00665 } 00666 } 00667 } 00668 00669 void Primitive::updateControls() 00670 { 00671 if (show_measure_control_) 00672 { 00673 removeMeasureControl(); 00674 addMeasureControl(); 00675 } 00676 if (show_rotation_control_) 00677 { 00678 removeRotationControls(); 00679 addRotationControls(); 00680 } 00681 if (show_movement_control_) 00682 { 00683 removeMovementControls(); 00684 addMovementControls(); 00685 } 00686 if (show_description_control_) 00687 { 00688 removeDescriptionControl(); 00689 addDescriptionControl(); 00690 } 00691 if (show_scale_control_) 00692 { 00693 updateScaleControls(); 00694 } 00695 } 00696 00697 void Primitive::clearObject() 00698 { 00699 control_.markers.clear(); 00700 object_.controls.clear(); 00701 updateControls(); 00702 } 00703 00704 void Primitive::changeColor(ColorRGBA color) 00705 { 00706 color_ = color; 00707 control_.markers.clear(); 00708 object_.controls.clear(); 00709 insert(); 00710 } 00711 00712 float maxScale(Vector3 scale) 00713 { 00714 if (scale.x > scale.y) 00715 { 00716 if (scale.x > scale.z) 00717 { 00718 return scale.x; 00719 } 00720 else 00721 { 00722 return scale.z; 00723 } 00724 } 00725 else 00726 { 00727 if (scale.y > scale.z) 00728 { 00729 return scale.y; 00730 } 00731 else 00732 { 00733 return scale.z; 00734 } 00735 } 00736 } 00737 00738 float minScale(Vector3 scale) 00739 { 00740 if (scale.x < scale.y) 00741 { 00742 if (scale.x < scale.z) 00743 { 00744 return scale.x; 00745 } 00746 else 00747 { 00748 return scale.z; 00749 } 00750 } 00751 else 00752 { 00753 if (scale.y < scale.z) 00754 { 00755 return scale.y; 00756 } 00757 else 00758 { 00759 return scale.z; 00760 } 00761 } 00762 } 00763 00764 }