MILDRobotModelWithExactIK.cpp
Go to the documentation of this file.
00001 
00020 #include <glpk.h>
00021 #include <limits>
00022 #include <ros/ros.h>
00023 #include <ros/node_handle.h>
00024 
00025 #include "robot_model_services/robot_model/impl/MILDRobotModelWithExactIK.hpp"
00026 #include "robot_model_services/robot_model/impl/MILDRobotModel.hpp"
00027 #include "robot_model_services/helper/MathHelper.hpp"
00028 #include "robot_model_services/rating/impl/AngleApproximationIKRatingModule.h"
00029 #include "robot_model_services/rating/impl/NavigationPathIKRatingModule.h"
00030 #include "robot_model_services/rating/impl/SimpleIKRatingModule.h"
00031 
00032 #include "nav_msgs/GetPlan.h"
00033 #include "geometry_msgs/PoseStamped.h"
00034 #include "geometry_msgs/Point.h"
00035 
00036 #include "urdf/model.h"
00037 #include "urdf_model/joint.h"
00038 #include <tf/tf.h>
00039 #include <tf_conversions/tf_eigen.h>
00040 #include <tf/transform_datatypes.h>
00041 #include <tf_conversions/tf_eigen.h>
00042 //#include <robot_state_publisher/robot_state_publisher.h>
00043 #include <kdl_parser/kdl_parser.hpp>
00044 #include <kdl/chain.hpp>
00045 #include <kdl/chainfksolver.hpp>
00046 #include <kdl/chainfksolverpos_recursive.hpp>
00047 #include <tf_conversions/tf_eigen.h>
00048 
00049 #include <locale>
00050 
00051 #include <visualization_msgs/Marker.h>
00052 
00053 namespace robot_model_services {
00054     MILDRobotModelWithExactIK::MILDRobotModelWithExactIK() : MILDRobotModel() {
00055         mDebugHelperPtr = DebugHelper::getInstance();
00056 
00057         mDebugHelperPtr->write(std::stringstream() << "STARTING MILD ROBOT MODEL WITH EXACT IK", DebugHelper::ROBOT_MODEL);
00058 
00059         navigationCostClient = n.serviceClient<nav_msgs::GetPlan>("/move_base/make_plan");
00060         double inverseKinematicIterationAccuracy_, ncp_, fcp_;
00061         int panAngleSamplingStepsPerIteration_;
00062         bool visualizeIK_;
00063         std::string IKAngleRating_;
00064         n.getParam("panAngleSamplingStepsPerIteration", panAngleSamplingStepsPerIteration_);
00065         n.getParam("inverseKinematicIterationAccuracy", inverseKinematicIterationAccuracy_);
00066         n.getParam("visualizeIK", visualizeIK_);
00067         n.getParam("ncp", ncp_);
00068         n.getParam("fcp", fcp_);
00069         if (visualizeIK_)
00070         {
00071             mDebugHelperPtr->write("IK Visualization ENABLED", DebugHelper::PARAMETERS);
00072         }
00073         else
00074         {
00075             mDebugHelperPtr->write("IK Visualization DISABLED", DebugHelper::PARAMETERS);
00076         }
00077         mPanAngleSamplingStepsPerIteration = panAngleSamplingStepsPerIteration_;
00078         mViewPointDistance = (ncp_ + fcp_)/2.0;
00079         mInverseKinematicIterationAccuracy = inverseKinematicIterationAccuracy_;
00080         mVisualizeIK = visualizeIK_;
00081         mDebugHelperPtr->write(std::stringstream() << "mPanAngleSamplingStepsPerIteration: " << mPanAngleSamplingStepsPerIteration, DebugHelper::PARAMETERS);
00082         mDebugHelperPtr->write(std::stringstream() << "mInverseKinematicIterationAccuracy: " << mInverseKinematicIterationAccuracy, DebugHelper::PARAMETERS);
00083         mDebugHelperPtr->write(std::stringstream() << "mViewPointDistance: " << mViewPointDistance, DebugHelper::PARAMETERS);
00084         //Temporary Visualization Publisher
00085         std::string IKVisualization;
00086         n.getParam("IKVisualization", IKVisualization);
00087         vis_pub = n.advertise<visualization_msgs::Marker>(IKVisualization, 1000);
00088         tfParametersInitialized = setUpTFParameters();
00089         n.getParam("IKAngleRating", IKAngleRating_);
00090         //IKAngleRating_ = std::toupper(IKAngleRating_);
00091         if (IKAngleRating_ == "ANGLE_APPROXIMATION")
00092         {
00093             ikRatingModule = AngleApproximationIKRatingModulePtr(new AngleApproximationIKRatingModule());
00094             mDebugHelperPtr->write(std::stringstream() << "Using AngleApproximation as IK angle rating algorithm", DebugHelper::PARAMETERS);
00095         }
00096         else if (IKAngleRating_ == "NAVIGATION_PATH")
00097         {
00098             ikRatingModule = NavigationPathIKRatingModulePtr(new NavigationPathIKRatingModule(RobotModelPtr(this)));
00099             mDebugHelperPtr->write(std::stringstream() << "Using NavigationPath as IK angle rating algorithm", DebugHelper::PARAMETERS);
00100         }
00101         else if (IKAngleRating_ == "SIMPLE")
00102         {
00103             ikRatingModule = SimpleIKRatingModulePtr(new SimpleIKRatingModule());
00104             mDebugHelperPtr->write(std::stringstream() << "Using SimpleIKRating as IK angle rating algorithm", DebugHelper::PARAMETERS);
00105         }
00106         else
00107         {
00108             ikRatingModule = SimpleIKRatingModulePtr(new SimpleIKRatingModule());
00109             ROS_WARN_STREAM("'" << IKAngleRating_ << "' is not a valid IK rating algorithm! Using the SimpleIKRating algorithm instead.");
00110         }
00111         mNumberIKCalls = 0;
00112         mnTotalIKTime = 0.0;
00113         mIKVisualizationLastIterationCount = IKVisualizationMaximunIterationCount;
00114         }
00115 
00116     MILDRobotModelWithExactIK::~MILDRobotModelWithExactIK() {}
00117 
00118     void MILDRobotModelWithExactIK::setViewPointDistance(float viewPointDistance) {
00119         this->mViewPointDistance = viewPointDistance;
00120         mDebugHelperPtr->write(std::stringstream() << "viewPointDistance set to: " << viewPointDistance, DebugHelper::PARAMETERS);
00121 
00122     }
00123 
00124 
00125     PTUConfig MILDRobotModelWithExactIK::calculateCameraPoseCorrection(const RobotStatePtr &sourceRobotState, const SimpleVector3 &position, const SimpleQuaternion &orientation)
00126     {
00127         MILDRobotStatePtr sourceMILDRobotState = boost::static_pointer_cast<MILDRobotState>(sourceRobotState);
00128         //Make sure the necessary geometry parameters are initialized
00129         mDebugHelperPtr->writeNoticeably("STARTING CALCULATE-CAMERA-POSE-CORRECTION METHOD", DebugHelper::ROBOT_MODEL);
00130         if (!tfParametersInitialized)
00131         {
00132             tfParametersInitialized = setUpTFParameters();
00133             if (!tfParametersInitialized)
00134             {
00135                 ROS_ERROR_STREAM("Could not extract parameters from tf.");
00136                 mDebugHelperPtr->writeNoticeably("ENDING CALCULATE-CAMERA-POSE-CORRECTION METHOD", DebugHelper::ROBOT_MODEL);
00137                 return PTUConfig(0.0,0.0);
00138             }
00139         }
00140         Eigen::Vector3d basePosition(sourceMILDRobotState->x, sourceMILDRobotState->y, 0.0);
00141         //Calculate pose of the pan joint
00142         Eigen::Affine3d basePoseEigen = Eigen::Translation3d(basePosition) * Eigen::AngleAxisd((double)(sourceMILDRobotState->rotation), Eigen::Vector3d::UnitZ());
00143         Eigen::Affine3d panJointEigen = basePoseEigen * baseToPanEigen;
00144         //Calculate the target center point
00145         Eigen::Quaterniond targetOrientation(orientation.w(), orientation.x(), orientation.y(), orientation.z());
00146         Eigen::Vector3d targetViewVector = targetOrientation.toRotationMatrix() * Eigen::Vector3d::UnitX();
00147         Eigen::Vector3d target_view_center_point = Eigen::Vector3d(position[0], position[1], position[2]) + targetViewVector*mViewPointDistance;
00148         //Visualize target view
00149         if (vis_pub.getNumSubscribers() > 0)
00150         {
00151             Eigen::Vector3d target_cam_point(position[0], position[1], position[2]);
00152             visualizeIKCameraTarget(target_view_center_point, target_cam_point);
00153         }
00154         //Calculate PAN
00155         Eigen::Vector3d panJointToCenterPointProjected(target_view_center_point[0] - panJointEigen(0,3), target_view_center_point[1] - panJointEigen(1,3), 0.0);
00156         double viewTriangleXYPlane_sideA = panJointToCenterPointProjected.norm();
00157         double viewTriangleXYPlane_sideB = sqrt(pow(viewTriangleXYPlane_sideA, 2.0) - pow(viewTriangleXYPlane_sideC, 2.0));
00158         double viewTriangleXYPlane_AngleBeta = pow(viewTriangleXYPlane_sideA, 2.0) + pow(viewTriangleXYPlane_sideC, 2.0) - pow(viewTriangleXYPlane_sideB, 2.0);
00159         viewTriangleXYPlane_AngleBeta = viewTriangleXYPlane_AngleBeta/(2.0*viewTriangleXYPlane_sideA*viewTriangleXYPlane_sideC);
00160         viewTriangleXYPlane_AngleBeta = acos(viewTriangleXYPlane_AngleBeta);
00161         Eigen::Vector3d panJointXAxis(panJointEigen(0,0), panJointEigen(1,0), panJointEigen(2,0));
00162         Eigen::Vector3d panJointYAxis(panJointEigen(0,1), panJointEigen(1,1), panJointEigen(2,1));
00163         panJointXAxis.normalize();
00164         panJointYAxis.normalize();
00165         panJointToCenterPointProjected.normalize();
00166         double panAngle = viewTriangleXYPlane_AngleBeta - (M_PI/2.0 - asin(panJointToCenterPointProjected.dot(panJointYAxis)));
00167         if(panJointToCenterPointProjected.dot(panJointXAxis) < 0) panAngle = M_PI - panAngle;   //If target is behind the robot, correct angle
00168         mDebugHelperPtr->write(std::stringstream() << "viewTriangleXYPlane_sideA: " << viewTriangleXYPlane_sideA, DebugHelper::ROBOT_MODEL);
00169         mDebugHelperPtr->write(std::stringstream() << "viewTriangleXYPlane_sideB: " << viewTriangleXYPlane_sideB, DebugHelper::ROBOT_MODEL);
00170         mDebugHelperPtr->write(std::stringstream() << "viewTriangleXYPlane_sideC: " << viewTriangleXYPlane_sideC, DebugHelper::ROBOT_MODEL);
00171         mDebugHelperPtr->write(std::stringstream() << "viewTriangleXYPlane_AngleBeta: " << viewTriangleXYPlane_AngleBeta, DebugHelper::ROBOT_MODEL);
00172         mDebugHelperPtr->write(std::stringstream() << "asin(panJointToCenterPointProjected.dot(panJointYAxis)): " << asin(panJointToCenterPointProjected.dot(panJointYAxis)),
00173                     DebugHelper::ROBOT_MODEL);
00174         mDebugHelperPtr->write(std::stringstream() << "mPanAngleOffset: " << mPanAngleOffset, DebugHelper::ROBOT_MODEL);
00175         mDebugHelperPtr->write(std::stringstream() << "panJointToCenterPointProjected.dot(panJointXAxis): " << panJointToCenterPointProjected.dot(panJointXAxis),
00176                     DebugHelper::ROBOT_MODEL);
00177         //Calculate TILT
00178         Eigen::Affine3d panJointRotatedEigen = panJointEigen * Eigen::AngleAxisd(panAngle, Eigen::Vector3d::UnitZ());
00179         Eigen::Affine3d tiltJointEigen = panJointRotatedEigen * panToTiltEigen;
00180         Eigen::Vector3d tiltJointToViewCenter = target_view_center_point - Eigen::Vector3d(tiltJointEigen(0,3), tiltJointEigen(1,3), tiltJointEigen(2,3));
00181         Eigen::Vector3d tiltJointYAxis(tiltJointEigen(0,1), tiltJointEigen(1,1), tiltJointEigen(2,1));
00182         tiltJointYAxis.normalize();
00183         Eigen::Vector3d tiltJointToViewCenterProjected = tiltJointToViewCenter - tiltJointYAxis.dot(tiltJointToViewCenter) * tiltJointYAxis;
00184         double viewTriangleZPlane_sideA = tiltJointToViewCenterProjected.norm();
00185         double bTimesCos = viewTriangleZPlane_sideB*cos(viewTriangleZPlane_angleAlpha);
00186         double viewTriangleZPlane_sideC = - bTimesCos/2.0 + sqrt(pow(bTimesCos,2.0)/4.0-pow(viewTriangleZPlane_sideB,2.0)+pow(viewTriangleZPlane_sideA,2.0));
00187 
00188         mDebugHelperPtr->write(std::stringstream() << "viewTriangleZPlane_sideA: " << viewTriangleZPlane_sideA, DebugHelper::ROBOT_MODEL);
00189         mDebugHelperPtr->write(std::stringstream() << "viewTriangleZPlane_sideB: " << viewTriangleZPlane_sideB, DebugHelper::ROBOT_MODEL);
00190         mDebugHelperPtr->write(std::stringstream() << "viewTriangleZPlane_sideC: " << viewTriangleZPlane_sideC, DebugHelper::ROBOT_MODEL);
00191 
00192         double viewTriangleZPlane_angleGamma = pow(viewTriangleZPlane_sideB, 2.0) + pow(viewTriangleZPlane_sideA, 2.0) - pow(viewTriangleZPlane_sideC, 2.0);
00193         viewTriangleZPlane_angleGamma = acos(viewTriangleZPlane_angleGamma / (2.0*viewTriangleZPlane_sideB*viewTriangleZPlane_sideA));
00194         double tiltAngle = viewTriangleZPlane_angleGamma - acos(tiltJointToViewCenter[2]/tiltJointToViewCenter.norm());
00195 
00196         //Check angle angle constrains and truncate values if neccessaire
00197         double tiltMin = mTiltLimits.get<0>();
00198         double tiltMax = mTiltLimits.get<1>();
00199         if (tiltAngle < tiltMin)
00200         {
00201             if (tiltAngle < tiltMin - 10.0) {
00202                 ROS_WARN_STREAM("Calculated Tilt-Angle was too small: " << tiltAngle*(180.0/M_PI));
00203             } else {
00204                 mDebugHelperPtr->write(std::stringstream() << "Calculated Tilt-Angle was too small: " << tiltAngle*(180.0/M_PI), DebugHelper::ROBOT_MODEL);
00205             }
00206             tiltAngle = tiltMin;
00207         }
00208         if (tiltAngle > tiltMax)
00209         {
00210             if (tiltAngle > tiltMax + 10.0) {
00211                 ROS_WARN_STREAM("Calculated Tilt-Angle was too high: " << tiltAngle*(180.0/M_PI));
00212             } else {
00213                 mDebugHelperPtr->write(std::stringstream() << "Calculated Tilt-Angle was too high: " << tiltAngle*(180.0/M_PI), DebugHelper::ROBOT_MODEL);
00214             }
00215             tiltAngle = tiltMax;
00216         }
00217 
00218         double panMin = mPanLimits.get<0>();
00219         double panMax = mPanLimits.get<1>();
00220         if (panAngle < panMin)
00221         {
00222             if (panAngle < panMin - 10.0) {
00223                 ROS_WARN_STREAM("Calculated Pan-Angle was too small: " << panAngle*(180.0/M_PI));
00224             } else {
00225                 mDebugHelperPtr->write(std::stringstream() << "Calculated Pan-Angle was too small: " << panAngle*(180.0/M_PI), DebugHelper::ROBOT_MODEL);
00226             }
00227             panAngle = panMin;
00228         }
00229         if (panAngle > panMax)
00230         {
00231             if (panAngle > panMax + 10.0) {
00232                 ROS_WARN_STREAM("Calculated Pan-Angle was too high: " << panAngle*(180.0/M_PI));
00233             } else {
00234                 mDebugHelperPtr->write(std::stringstream() << "Calculated Pan-Angle was too high: " << panAngle*(180.0/M_PI), DebugHelper::ROBOT_MODEL);
00235             }
00236             panAngle = panMax;
00237         }
00238 
00239         //visualize current robot configuration and corrected view target
00240         if (vis_pub.getNumSubscribers() > 0)
00241         {
00242             Eigen::Vector3d baseOrientation(basePoseEigen(0,0), basePoseEigen(1,0), basePoseEigen(2,0));
00243             Eigen::Vector3d pan_base_point(panJointEigen(0,3), panJointEigen(1,3), panJointEigen(2,3));
00244             Eigen::Vector3d pan_rotated_point(panJointRotatedEigen(0,3), panJointRotatedEigen(1,3), panJointRotatedEigen(2,3));
00245             Eigen::Vector3d tilt_base_point(tiltJointEigen(0,3), tiltJointEigen(1,3), tiltJointEigen(2,3));
00246             Eigen::Affine3d camFrame = tiltJointEigen * Eigen::AngleAxisd(-tiltAngle, Eigen::Vector3d::UnitY()) * tiltToCameraEigen;
00247             Eigen::Vector3d cam_point(camFrame(0,3), camFrame(1,3), camFrame(2,3));
00248             Eigen::Affine3d actualViewCenterEigen = camFrame * Eigen::Translation3d(Eigen::Vector3d(0.0, 0.0, viewTriangleZPlane_sideA));
00249             Eigen::Vector3d actual_view_center_point(actualViewCenterEigen(0,3), actualViewCenterEigen(1,3), actualViewCenterEigen(2,3));
00250             visualizeCameraPoseCorrection(basePosition, baseOrientation, pan_base_point, pan_rotated_point, tilt_base_point,cam_point, actual_view_center_point);
00251         }
00252 
00253         mDebugHelperPtr->writeNoticeably("ENDING CALCULATE-CAMERA-POSE-CORRECTION METHOD", DebugHelper::ROBOT_MODEL);
00254         return PTUConfig(panAngle,tiltAngle);
00255     }
00256 
00257 
00258     //Solves the inverse kinematical problem for an given robot state and a pose for the camera
00259     RobotStatePtr MILDRobotModelWithExactIK::calculateRobotState(const RobotStatePtr &sourceRobotState, const SimpleVector3 &position, const SimpleQuaternion &orientation)
00260     {
00261         mDebugHelperPtr->writeNoticeably("STARTING CALCULATE-ROBOT-STATE METHOD", DebugHelper::ROBOT_MODEL);
00262         std::clock_t begin = std::clock();
00263 
00264         MILDRobotStatePtr sourceMILDRobotState = boost::static_pointer_cast<MILDRobotState>(sourceRobotState);
00265         MILDRobotStatePtr targetMILDRobotState(new MILDRobotState());
00266         targetMILDRobotState->pan = 0;
00267         targetMILDRobotState->tilt = 0;
00268         targetMILDRobotState->rotation = 0;
00269         targetMILDRobotState->x = 0;
00270         targetMILDRobotState->y = 0;
00271 
00272         double tiltMin = mTiltLimits.get<0>();
00273         double tiltMax = mTiltLimits.get<1>();
00274 
00275         if (mVisualizeIK && vis_pub.getNumSubscribers() > 0) {this->resetIKVisualization();}
00276 
00277         //Make sure the necessary geometry parameters are initialized
00278         if (!tfParametersInitialized)
00279         {
00280             tfParametersInitialized = setUpTFParameters();
00281             if (!tfParametersInitialized)
00282             {
00283                 ROS_ERROR_STREAM("Could not extract parameters from tf.");
00284                 mDebugHelperPtr->writeNoticeably("ENDING CALCULATE-ROBOT-STATE METHOD", DebugHelper::ROBOT_MODEL);
00285                 return targetMILDRobotState;
00286             }
00287         }
00288         Eigen::Quaterniond targetOrientation(orientation.w(), orientation.x(), orientation.y(), orientation.z());
00289         Eigen::Vector3d targetViewVector = targetOrientation.toRotationMatrix() * Eigen::Vector3d::UnitX();
00290 
00291         //The plane normal is now defined as the negative cross product of the camera view vector and the z axis.
00292         //Any rotation around the view axis will be ignored to ensure that the resulting target camera pose is valid
00293         Eigen::Vector3d planeNormal = -targetViewVector.cross(Eigen::Vector3d::UnitZ());
00294         planeNormal.normalize(); targetViewVector.normalize();
00295 
00296         mDebugHelperPtr->write(std::stringstream() << "Source state: (Pan: " << sourceMILDRobotState->pan
00297                                 << ", Tilt: " << sourceMILDRobotState->tilt
00298                                 << ", Rotation " << sourceMILDRobotState->rotation
00299                                 << ", X:" << sourceMILDRobotState->x
00300                                 << ", Y:" << sourceMILDRobotState->y << ")",
00301                     DebugHelper::ROBOT_MODEL);
00302         mDebugHelperPtr->write(std::stringstream() << "Target Position: " << position[0] << ", " << position[1] << ", " << position[2],
00303                     DebugHelper::ROBOT_MODEL);
00304         mDebugHelperPtr->write(std::stringstream() << "Target Orientation: " << targetOrientation.w() << ", " << targetOrientation.x() << ", " << targetOrientation.y()<< ", " << targetOrientation.z(),
00305                     DebugHelper::ROBOT_MODEL);
00306         //Visualize target camera pose & target viewcenter
00307         Eigen::Vector3d target_view_center_point = Eigen::Vector3d(position[0], position[1], position[2]) + targetViewVector*mViewPointDistance;
00308 
00309         if (mVisualizeIK && vis_pub.getNumSubscribers() > 0)
00310         {
00311             mDebugHelperPtr->write(std::stringstream() << "Publishing Camera Target from (" << position[0] << ", " << position[1] << ", " << position[2] << ") to (" << target_view_center_point[0] << ", " << target_view_center_point[1] << ", " << target_view_center_point[2] << ")",  DebugHelper::ROBOT_MODEL);
00312             Eigen::Vector3d target_cam_point(position[0], position[1], position[2]);
00313             visualizeIKCameraTarget(target_view_center_point, target_cam_point);
00314         }
00315 
00316         //Calculate TILT and position of Tilt joint
00317         double tilt; Eigen::Vector3d tilt_base_point_projected;
00318         if (!getTiltAngleAndTiltBasePointProjected(planeNormal, targetViewVector, target_view_center_point, tilt, tilt_base_point_projected))
00319         {
00320              ROS_ERROR_STREAM("No solution found for center point (" << position[0] << ", " << position[1] << ", " << position[2] << ")");
00321              mDebugHelperPtr->writeNoticeably("ENDING CALCULATE-ROBOT-STATE METHOD", DebugHelper::ROBOT_MODEL);
00322              return targetMILDRobotState;
00323         }
00324         mDebugHelperPtr->write(std::stringstream() << "tilt_base_point_projected: " << tilt_base_point_projected[0] << ", " << tilt_base_point_projected[1] << ", " << tilt_base_point_projected[2],
00325                     DebugHelper::ROBOT_MODEL);
00326         if (tilt < tiltMin)
00327         {
00328             if (tilt < tiltMin - 10.0) {
00329                 ROS_WARN_STREAM("Calculated Tilt-Angle was too small: " << tilt*(180.0/M_PI));
00330             } else {
00331                 mDebugHelperPtr->write(std::stringstream() << "Calculated Tilt-Angle was too small: " << tilt*(180.0/M_PI), DebugHelper::ROBOT_MODEL);
00332             }
00333             tilt = tiltMin;
00334         }
00335         if (tilt > tiltMax)
00336         {
00337             if (tilt > tiltMax + 10.0) {
00338                 ROS_WARN_STREAM("Calculated Tilt-Angle was too high: " << tilt*(180.0/M_PI));
00339             } else {
00340                 mDebugHelperPtr->write(std::stringstream() << "Calculated Tilt-Angle was too high: " << tilt*(180.0/M_PI), DebugHelper::ROBOT_MODEL);
00341             }
00342             tilt = tiltMax;
00343         }
00344         mDebugHelperPtr->write(std::stringstream() << "Tilt: " << tilt*(180.0/M_PI) << " deg",
00345                     DebugHelper::ROBOT_MODEL);
00346 
00347         Eigen::Vector3d tilt_base_point = tilt_base_point_projected + x_product*planeNormal;
00348         mDebugHelperPtr->write(std::stringstream() << "tilt_base_point: " << tilt_base_point[0] << ", " << tilt_base_point[1] << ", " << tilt_base_point[2],
00349                     DebugHelper::ROBOT_MODEL);
00350 
00351         // Get pose of PAN joint
00352         Eigen::Affine3d tiltFrame = getTiltJointFrame(planeNormal, targetViewVector,  tilt_base_point);
00353         Eigen::Affine3d tiltedFrame =  tiltFrame * Eigen::AngleAxisd(-tilt, Eigen::Vector3d::UnitY());
00354         Eigen::Affine3d camFrame = tiltedFrame * tiltToCameraEigen;
00355         Eigen::Affine3d actualViewCenterEigen(Eigen::Translation3d(Eigen::Vector3d(0.0, 0.0, mViewPointDistance)));
00356         actualViewCenterEigen = camFrame*actualViewCenterEigen;
00357 
00358         Eigen::Affine3d pan_rotated_Frame = tiltFrame * tiltToPanEigen;
00359 
00360         //Calculate PAN and base rotation
00361         double pan = this->getPanAngleFromPanJointPose(pan_rotated_Frame, sourceMILDRobotState);
00362         mDebugHelperPtr->write(std::stringstream() << "Pan: " << pan*(180.0/M_PI) << " deg", DebugHelper::ROBOT_MODEL);
00363 
00364         Eigen::Affine3d pan_Frame = pan_rotated_Frame * Eigen::AngleAxisd(pan, Eigen::Vector3d::UnitZ());
00365         Eigen::Affine3d base_Frame = pan_Frame * panToBaseEigen;
00366 
00367         //Visualization
00368         if (mVisualizeIK) // && vis_pub.getNumSubscribers() > 0)
00369         {
00370             Eigen::Vector3d base_point(base_Frame(0,3), base_Frame(1,3), base_Frame(2,3));
00371             Eigen::Vector3d pan_base_point(pan_Frame(0,3), pan_Frame(1,3), pan_Frame(2,3));
00372             Eigen::Vector3d pan_rotated_point(pan_rotated_Frame(0,3), pan_rotated_Frame(1,3), pan_rotated_Frame(2,3));
00373             Eigen::Vector3d cam_point(camFrame(0,3), camFrame(1,3), camFrame(2,3));
00374             Eigen::Vector3d actual_view_center_point(actualViewCenterEigen(0,3), actualViewCenterEigen(1,3), actualViewCenterEigen(2,3));
00375             Eigen::Vector3d base_orientation(base_Frame(0,0), base_Frame(1,0), base_Frame(2,0));
00376             visualizeIKcalculation(base_point, base_orientation, pan_base_point, pan_rotated_point, tilt_base_point,tilt_base_point_projected, cam_point, actual_view_center_point);
00377         }
00378 
00379         // Set output values
00380                 // set pan
00381         targetMILDRobotState->pan = pan;
00382 
00383                 // set rotation
00384         targetMILDRobotState->rotation = this->getBaseAngleFromBaseFrame(base_Frame);
00385                 while (targetMILDRobotState->rotation < 0) { targetMILDRobotState->rotation += 2 * M_PI; };
00386                 while (targetMILDRobotState->rotation > 2 * M_PI) { targetMILDRobotState->rotation -= 2 * M_PI; };
00387 
00388                 // set tilt
00389         targetMILDRobotState->tilt = tilt;
00390 
00391                 // set x, y
00392         targetMILDRobotState->x = base_Frame(0,3);
00393         targetMILDRobotState->y = base_Frame(1,3);
00394         mDebugHelperPtr->write(std::stringstream() << "Target state: (Pan: " << targetMILDRobotState->pan << " rad"
00395                                 << ", Tilt: " << targetMILDRobotState->tilt << " rad"
00396                                 << ", Rotation " << targetMILDRobotState->rotation << " rad"
00397                                 << ", X: " << targetMILDRobotState->x << " m"
00398                                 << ", Y: " << targetMILDRobotState->y << " m)",
00399                     DebugHelper::ROBOT_MODEL);
00400 
00401 
00402         std::clock_t end = std::clock();
00403         double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
00404         mNumberIKCalls++;
00405         mnTotalIKTime += elapsed_secs;
00406         mDebugHelperPtr->write(std::stringstream() << "IK Calculation took " << elapsed_secs << " seconds. Total calculation time: "
00407                                 << mnTotalIKTime << " over " << mNumberIKCalls << " calculations.",
00408                     DebugHelper::ROBOT_MODEL);
00409 
00410         mDebugHelperPtr->writeNoticeably("ENDING CALCULATE-ROBOT-STATE METHOD", DebugHelper::ROBOT_MODEL);
00411         return targetMILDRobotState;
00412         }
00413 
00414     Eigen::Affine3d MILDRobotModelWithExactIK::getTiltJointFrame(Eigen::Vector3d &planeNormal, Eigen::Vector3d &targetViewVector,  Eigen::Vector3d &tilt_base_point)
00415     {
00416         Eigen::Vector3d viewDirection;
00417         viewDirection = targetViewVector;
00418         viewDirection[2] = 0.0;
00419         viewDirection.normalize();
00420         Eigen::Matrix4d tiltFrame_Rotation;
00421         tiltFrame_Rotation.col(0) << viewDirection[0], viewDirection[1],  0.0 , 0.0;
00422         tiltFrame_Rotation.col(1) << -planeNormal[0] , -planeNormal[1] ,  -planeNormal[2] ,0.0;
00423         tiltFrame_Rotation.col(2) << 0.0, 0.0, 1.0, 0.0;
00424         tiltFrame_Rotation.col(3) << tilt_base_point[0] , tilt_base_point[1] ,  tilt_base_point[2] , 1.0;
00425 
00426         Eigen::Affine3d tiltFrame(tiltFrame_Rotation);
00427         return tiltFrame;
00428     }
00429 
00430     bool MILDRobotModelWithExactIK::getTiltAngleAndTiltBasePointProjected(Eigen::Vector3d &planeNormal, Eigen::Vector3d &targetViewVector,  Eigen::Vector3d &target_view_center_point, double &tilt, Eigen::Vector3d &tilt_base_point_projected)
00431     {
00432         //Calculate tilt base point (t1, t2, t3)
00433         double t1, t2, t3;
00434         //Calculate t3 using h
00435         t3 = h_tilt - target_view_center_point[2];
00436         //Calculate t2 using abc-formula
00437         double a, b, c;
00438         double planeNormalX = planeNormal.x();
00439 
00440         // in case planeNormalX is zero, calculation can be done in an easier way
00441         if (fabs(planeNormalX) < 10e-7)
00442         {
00443             mDebugHelperPtr->write(std::stringstream() << "PlaneNormalX is zero", DebugHelper::ROBOT_MODEL);
00444             //Note: I will assume here, that x and y cannot both be zero, since the plane normal has to lie in the XY-plane
00445             t2 = -(t3*planeNormal[2])/planeNormal[1];
00446             t1 = pow(viewTriangleZPlane_sideA, 2.0) - pow(t2, 2.0) - pow(t3, 2.0);
00447             // if t1 < 0, so solution can be found
00448             if (t1 < 0) 
00449             {
00450               return false;
00451             }
00452             t1 = sqrt(t1);
00453             
00454             //Note: The equation solved above has a positive and negative solution. The correct one is whichever points in the same direction as the targetViewvector
00455             if (targetViewVector[0]*t1+targetViewVector[1]*t2 > 0)
00456             {
00457                 //-> Flip sign if needed
00458                 t1 *= -1.0;
00459             }
00460         }
00461         else // in any other case, a quadratic equation needs to be solved for t2 and t1 will be derived from the result
00462         {
00463             mDebugHelperPtr->write(std::stringstream() <<  "planNormalX NOT equal 0", DebugHelper::ROBOT_MODEL);
00464             a = 1 + pow(planeNormal(1)/planeNormalX, 2.0);
00465             b = (2*t3*planeNormal(1)*planeNormal(2))/pow(planeNormalX, 2.0);
00466             c = -pow(viewTriangleZPlane_sideA, 2.0) + pow(t3, 2.0)*(1+pow(planeNormal(2)/planeNormalX, 2.0));
00467             if (pow(b, 2.0)<4*a*c)
00468             {
00469                 return false;
00470             }
00471 
00472             double t2_1, t2_2, t1_1, t1_2;
00473             t2_1 = (-b + sqrt(pow(b, 2.0)-4*a*c))/(2*a);
00474             t2_2 = (-b - sqrt(pow(b, 2.0)-4*a*c))/(2*a);
00475             //Calculate feasible t1
00476             t1_1 = -(t2_1*planeNormal(1)+t3*planeNormal(2))/planeNormalX;
00477             t1_2 = -(t2_2*planeNormal(1)+t3*planeNormal(2))/planeNormalX;
00478             //Choose t1, t2
00479             if (targetViewVector[0]*t1_1+targetViewVector[1]*t2_1 < 0)
00480             {
00481                 t1 = t1_1;
00482                 t2 = t2_1;
00483             }
00484             else
00485             {
00486                 t1 = t1_2;
00487                 t2 = t2_2;
00488             }
00489         }
00490 
00491         //get projected tilt base point
00492         tilt_base_point_projected = Eigen::Vector3d(t1+target_view_center_point[0], t2+target_view_center_point[1], t3+target_view_center_point[2]);
00493         //get tilt angle
00494         Eigen::Vector3d targetToBase(tilt_base_point_projected[0]-target_view_center_point[0], tilt_base_point_projected[1]-target_view_center_point[1], tilt_base_point_projected[2]-target_view_center_point[2]);
00495         targetToBase.normalize();
00496         double targetToBase_Angle = acos(targetToBase[2]);
00497         mDebugHelperPtr->write(std::stringstream() << "targetToBase_Angle: " << targetToBase_Angle, DebugHelper::ROBOT_MODEL);
00498         tilt = targetToBase_Angle+mTiltAngleOffset;
00499         return true;
00500     }
00501 
00502 
00503 
00504     double MILDRobotModelWithExactIK::getPanAngleFromPanJointPose(Eigen::Affine3d &panJointFrame, MILDRobotStatePtr &robotState)
00505     {
00506         unsigned int iterationCount = 1;
00507         double phiMin = mPanLimits.get<0>();
00508         double phiMax = mPanLimits.get<1>();
00509         double currentBestAngle = (phiMax-phiMin)/2.0+phiMin;
00510         double currentBestRating, newBestRating = 0.0;
00511         double currentAngleRange = phiMax-phiMin;
00512         geometry_msgs::Point actualRobotPosition, targetRobotPosition;
00513         actualRobotPosition.x = robotState->x;
00514         actualRobotPosition.y = robotState->y;
00515         actualRobotPosition.z = targetRobotPosition.z = 0.0;
00516         Eigen::Affine3d baseFrame;
00517         mDebugHelperPtr->write(std::stringstream() << "phiMin: " << phiMin << " phiMax: " << phiMax, DebugHelper::ROBOT_MODEL);
00518         mDebugHelperPtr->write(std::stringstream() << "currentAngleRange: " << currentAngleRange << " currentBestAngle: " << currentBestAngle,
00519                     DebugHelper::ROBOT_MODEL);
00520         mDebugHelperPtr->write(std::stringstream() << "mPanAngleSamplingStepsPerIteration: " << mPanAngleSamplingStepsPerIteration,
00521                     DebugHelper::ROBOT_MODEL);
00522         Eigen::Vector3d basePoint, basePoint2;
00523         Eigen::Vector3d baseOrientation;
00524         //do sampling
00525         do
00526         {
00527             std::ostringstream converter;
00528             converter << iterationCount;
00529             std::string nsIterationVector = std::string("iterationVector") + converter.str();
00530             double angleStepSize = currentAngleRange / mPanAngleSamplingStepsPerIteration;
00531             double currentIterationAngle, currentRating, angleCenter;
00532             currentBestRating = newBestRating;
00533             angleCenter = currentBestAngle;
00534             newBestRating = -1.0;
00535             for (unsigned int i = 0; i < mPanAngleSamplingStepsPerIteration; i++)
00536             {
00537                 currentIterationAngle = angleCenter - currentAngleRange/2.0 + i * angleStepSize;
00538                 if (phiMax>currentIterationAngle && phiMin<currentIterationAngle)
00539                 {
00540                     //Calculate the base frame with respect to the current angle
00541                     baseFrame = panJointFrame * Eigen::AngleAxisd(-currentIterationAngle, Eigen::Vector3d::UnitZ()) * panToBaseEigen;
00542                     basePoint = Eigen::Vector3d(baseFrame(0,3),baseFrame(1,3),baseFrame(2,3));
00543                     baseOrientation = Eigen::Vector3d(baseFrame(0,0),baseFrame(1,0),baseFrame(2,0));
00544                     baseOrientation.normalize();
00545                     basePoint2 = basePoint+baseOrientation*0.15;
00546                     targetRobotPosition.x = baseFrame(0,3);
00547                     targetRobotPosition.y = baseFrame(1,3);
00548                     float baseAngle = getBaseAngleFromBaseFrame(baseFrame);
00549                     currentRating = ikRatingModule->getPanAngleRating(actualRobotPosition, targetRobotPosition, robotState->rotation, baseAngle);
00550                     mDebugHelperPtr->write(std::stringstream() << "PTU-Angle: " << currentIterationAngle << " with base angle: " << baseAngle << " and rating: " << currentRating,
00551                                 DebugHelper::ROBOT_MODEL);
00552                     if (currentRating > newBestRating)
00553                     {
00554                         newBestRating = currentRating;
00555                         currentBestAngle = currentIterationAngle;
00556                     }
00557                     if (mVisualizeIK && vis_pub.getNumSubscribers() > 0)
00558                     {
00559                         Eigen::Vector4d color_succeeded(1.0-currentRating,currentRating, 0.0, 1.0);
00560                         //visualizeIKPoint(basePoint, color_succeeded, nsIterationVector, 2*i);
00561                         visualizeIKArrowSmall(basePoint, basePoint2, color_succeeded, nsIterationVector, 2*i+1);
00562                     }
00563                 }
00564             }
00565             mDebugHelperPtr->write(std::stringstream() << "Best angle: " << currentBestAngle << " with rating: " << newBestRating
00566                                     << " and angle range " << currentAngleRange,
00567                         DebugHelper::ROBOT_MODEL);
00568             currentAngleRange = currentAngleRange / 2.0;
00569             iterationCount++;
00570         //Loop while there is still significant change in the angle rating and while the maximum number of iterations has not yet been reached
00571         } while(fabs(currentBestRating-newBestRating) > mInverseKinematicIterationAccuracy && iterationCount <= IKVisualizationMaximunIterationCount);
00572 
00573         mIKVisualizationLastIterationCount = iterationCount;
00574         if (currentBestRating < 0.0) {ROS_ERROR_STREAM("No valid solution found for this pan frame.");}
00575         return -currentBestAngle;
00576     }
00577 
00578 
00579     bool MILDRobotModelWithExactIK::setUpTFParameters()
00580     {
00581         //Get Parameters from TF-Publishers
00582         tf::StampedTransform panToTiltTF, baseToPanTF, tiltToCamLeftTF, tiltToCamRightTF;
00583         Eigen::Affine3d tiltAxisPointEigen, tiltToCamLeftEigen, tiltToCamRightEigen, cameraLeftPointEigen, cameraRightPointEigen, cameraMidPointEigen;
00584         ROS_INFO_STREAM("Looking up tf transforms (" << mFrameName_map << " to " << mFrameName_mild_ptu_tilt_link_rotated << ")");
00585         ros::spinOnce();
00586         try
00587         {      
00588             //Wait for first transform to be published
00589             if (listener.waitForTransform(mFrameName_map, mFrameName_mild_ptu_tilt_link_rotated, ros::Time(), ros::Duration(4.0)))
00590             {
00591                 //Assume that tf is alive and lookups will be successful
00592                 listener.lookupTransform(mFrameName_mild_ptu_pan_link_rotated, mFrameName_mild_ptu_tilt_link, ros::Time(0), panToTiltTF);
00593                 listener.lookupTransform(mFrameName_mild_base, mFrameName_mild_ptu_pan_link, ros::Time(0), baseToPanTF);
00594                 listener.lookupTransform(mFrameName_mild_ptu_tilt_link_rotated, mFrameName_mild_camera_left, ros::Time(0), tiltToCamLeftTF);
00595                 listener.lookupTransform(mFrameName_mild_ptu_tilt_link_rotated, mFrameName_mild_camera_right, ros::Time(0), tiltToCamRightTF);
00596             }
00597             else
00598             {
00599                 ROS_ERROR("TF lookup timed out. Is the transformation publisher running?");
00600                 return false;
00601             }
00602         }
00603         catch (tf::TransformException ex)
00604         {
00605             ROS_ERROR("An error occured during tf-lookup: %s",ex.what());
00606             return false;
00607         }
00608         tf::poseTFToEigen(panToTiltTF, panToTiltEigen);
00609         tf::poseTFToEigen(baseToPanTF, baseToPanEigen);
00610         tf::poseTFToEigen(tiltToCamLeftTF, tiltToCamLeftEigen);
00611         tf::poseTFToEigen(tiltToCamRightTF, tiltToCamRightEigen);
00612 
00613         tiltAxisPointEigen = baseToPanEigen * panToTiltEigen;
00614         cameraLeftPointEigen = tiltAxisPointEigen * tiltToCamLeftEigen;
00615         cameraRightPointEigen = tiltAxisPointEigen * tiltToCamRightEigen;
00616 
00617         //Hacky-ish approach to get the center point between left and right camera
00618         cameraMidPointEigen = cameraLeftPointEigen;
00619         cameraMidPointEigen(0,3) = (cameraLeftPointEigen(0,3) + cameraRightPointEigen(0,3)) / 2.0;
00620         cameraMidPointEigen(1,3) = (cameraLeftPointEigen(1,3) + cameraRightPointEigen(1,3)) / 2.0;
00621         cameraMidPointEigen(2,3) = (cameraLeftPointEigen(2,3) + cameraRightPointEigen(2,3)) / 2.0;
00622         tiltToCameraEigen = tiltAxisPointEigen.inverse() * cameraMidPointEigen;
00623 
00624         tiltToPanEigen = panToTiltEigen.inverse();
00625         panToBaseEigen = baseToPanEigen.inverse();
00626         h_tilt = tiltAxisPointEigen.matrix()(2,3);
00627         mDebugHelperPtr->writeNoticeably(std::stringstream() << "Height above ground: " << h_tilt, DebugHelper::ROBOT_MODEL);
00628 
00629         Eigen::Vector3d cam_axis_x(cameraMidPointEigen(0,0), cameraMidPointEigen(1,0), cameraMidPointEigen(2,0));
00630         Eigen::Vector3d cam_axis_y(cameraMidPointEigen(0,1), cameraMidPointEigen(1,1), cameraMidPointEigen(2,1));
00631         Eigen::Vector3d cam_axis_z(cameraMidPointEigen(0,2), cameraMidPointEigen(1,2), cameraMidPointEigen(2,2));
00632         cam_axis_x.normalize();
00633         cam_axis_y.normalize();
00634         cam_axis_z.normalize();
00635         Eigen::Vector3d tilt_to_cam(tiltAxisPointEigen(0,3)-cameraMidPointEigen(0,3), tiltAxisPointEigen(1,3)-cameraMidPointEigen(1,3), tiltAxisPointEigen(2,3)-cameraMidPointEigen(2,3));
00636         x_product = cam_axis_x.dot(tilt_to_cam);
00637         tilt_to_cam -= x_product*cam_axis_x;
00638         viewTriangleZPlane_sideB = tilt_to_cam.norm();
00639         tilt_to_cam.normalize();
00640         viewTriangleZPlane_angleAlpha = acos(cam_axis_z.dot(tilt_to_cam));
00641         viewTriangleZPlane_sideA = sqrt(pow(mViewPointDistance,2.0)+pow(viewTriangleZPlane_sideB,2.0)-2*mViewPointDistance*viewTriangleZPlane_sideB*cos(viewTriangleZPlane_angleAlpha));
00642         viewTriangleZPlane_angleGamma = pow(mViewPointDistance, 2.0) - pow(viewTriangleZPlane_sideA,2.0)-pow(viewTriangleZPlane_sideB,2.0);
00643         viewTriangleZPlane_angleGamma = viewTriangleZPlane_angleGamma / (-2.0*viewTriangleZPlane_sideA*viewTriangleZPlane_sideB);
00644         viewTriangleZPlane_angleGamma = acos(viewTriangleZPlane_angleGamma);
00645         mTiltAngleOffset = viewTriangleZPlane_angleGamma-viewTriangleZPlane_angleAlpha-M_PI/2.0;
00646         //Calculate additional values for the camera pose correction
00647         Eigen::Affine3d panToCameraEigen = panToTiltEigen * tiltToCameraEigen;
00648         Eigen::Vector3d cam_axis_x_pan_coordinates(panToCameraEigen(0,2), panToCameraEigen(1,2), panToCameraEigen(2,2));
00649         Eigen::Vector3d cam_axis_z_pan_coordinates(panToCameraEigen(0,1), panToCameraEigen(1,1), panToCameraEigen(2,1));
00650         cam_axis_x_pan_coordinates.normalize();
00651         cam_axis_z_pan_coordinates.normalize();
00652         Eigen::Vector3d panToCameraNormal(panToCameraEigen(0,3), panToCameraEigen(1,3), panToCameraEigen(2,3));
00653         panToCameraNormal = panToCameraNormal - cam_axis_x_pan_coordinates * panToCameraNormal.dot(cam_axis_x_pan_coordinates) - cam_axis_z_pan_coordinates * panToCameraNormal.dot(cam_axis_z_pan_coordinates);
00654         viewTriangleXYPlane_sideC = panToCameraNormal.norm();
00655         panToCameraNormal.normalize();
00656         mPanAngleOffset = acos(panToCameraNormal.dot(Eigen::Vector3d::UnitX()));
00657         
00658         mDebugHelperPtr->writeNoticeably(std::stringstream() << "viewTriangleZPlane_angleAlpha: " << viewTriangleZPlane_angleAlpha, DebugHelper::ROBOT_MODEL);
00659         mDebugHelperPtr->writeNoticeably(std::stringstream() << "viewTriangleZPlane_angleGamma: " << viewTriangleZPlane_angleGamma, DebugHelper::ROBOT_MODEL);
00660         mDebugHelperPtr->writeNoticeably(std::stringstream() << "viewTriangleZPlane_sideA: " << viewTriangleZPlane_sideA, DebugHelper::ROBOT_MODEL);
00661         mDebugHelperPtr->writeNoticeably(std::stringstream() << "viewTriangleZPlane_sideB: " << viewTriangleZPlane_sideB, DebugHelper::ROBOT_MODEL);
00662         mDebugHelperPtr->writeNoticeably(std::stringstream() << "viewTriangleXYPlane_sideC: " << viewTriangleXYPlane_sideC, DebugHelper::ROBOT_MODEL);
00663         mDebugHelperPtr->writeNoticeably(std::stringstream() << "mTiltAngleOffset: " << mTiltAngleOffset, DebugHelper::ROBOT_MODEL);
00664         mDebugHelperPtr->writeNoticeably(std::stringstream() << "mPanAngleOffset: " << mPanAngleOffset, DebugHelper::ROBOT_MODEL);
00665 
00666         ROS_INFO_STREAM("TF lookup successful.");
00667 
00668         return true;
00669     }
00670 
00671     void MILDRobotModelWithExactIK::resetIKVisualization()
00672     {
00673         //NOTE: This method should basically just delete all previously created markers.
00674         //Since the DELETEALL option is not working under ROS indigo, I tried to delete each marker individually by using the DELETE method
00675         //This should be changed to a clean solution once the required options in ROS are working again 
00676         visualization_msgs::Marker resetMarker = visualization_msgs::Marker();
00677         resetMarker.id = 0;
00678         resetMarker.header.frame_id = mFrameName_map;
00679         resetMarker.action = visualization_msgs::Marker::DELETE;
00680         resetMarker.lifetime = ros::Duration();
00681         resetMarker.scale.x = 0.02;
00682         resetMarker.scale.y = 0.02;
00683         resetMarker.scale.z = 0.02;
00684         resetMarker.color.a = 0.0;
00685 
00686         //Reset camToActualViewCenterVector
00687         resetMarker.header.stamp = ros::Time::now();
00688         resetMarker.type = visualization_msgs::Marker::ARROW;
00689         resetMarker.ns = "camToActualViewCenterVector";
00690         vis_pub.publish(resetMarker);
00691         ros::spinOnce();
00692         //Reset tiltToCamVector
00693         resetMarker.header.stamp = ros::Time::now();
00694         resetMarker.type = visualization_msgs::Marker::ARROW;
00695         resetMarker.ns = "tiltToCamVector";
00696         vis_pub.publish(resetMarker);
00697         ros::spinOnce();
00698         //Reset tiltBaseVectorProjected
00699         resetMarker.header.stamp = ros::Time::now();
00700         resetMarker.type = visualization_msgs::Marker::SPHERE;
00701         resetMarker.ns = "tiltBaseVectorProjected";
00702         vis_pub.publish(resetMarker);
00703         ros::spinOnce();
00704         //Reset tiltBaseVector
00705         resetMarker.header.stamp = ros::Time::now();
00706         resetMarker.type = visualization_msgs::Marker::SPHERE;
00707         resetMarker.ns = "tiltBaseVector";
00708         vis_pub.publish(resetMarker);
00709         ros::spinOnce();
00710         //Reset panToTiltVector
00711         resetMarker.header.stamp = ros::Time::now();
00712         resetMarker.type = visualization_msgs::Marker::ARROW;
00713         resetMarker.ns = "panToTiltVector";
00714         vis_pub.publish(resetMarker);
00715         ros::spinOnce();
00716         //Reset panBaseVector
00717         resetMarker.header.stamp = ros::Time::now();
00718         resetMarker.type = visualization_msgs::Marker::SPHERE;
00719         resetMarker.ns = "panBaseVector";
00720         vis_pub.publish(resetMarker);
00721         ros::spinOnce();
00722         //Reset baseToPanVector
00723         resetMarker.header.stamp = ros::Time::now();
00724         resetMarker.type = visualization_msgs::Marker::ARROW;
00725         resetMarker.ns = "baseToPanVector";
00726         vis_pub.publish(resetMarker);
00727         ros::spinOnce();
00728         //Reset targetCameraVector
00729         resetMarker.header.stamp = ros::Time::now();
00730         resetMarker.type = visualization_msgs::Marker::ARROW;
00731         resetMarker.ns = "targetCameraVector";
00732         vis_pub.publish(resetMarker);
00733         ros::spinOnce();
00734         //Reset basePose
00735         resetMarker.header.stamp = ros::Time::now();
00736         resetMarker.type = visualization_msgs::Marker::SPHERE;
00737         resetMarker.ns = "basePose";
00738         vis_pub.publish(resetMarker);
00739         ros::spinOnce();
00740         resetMarker.type = visualization_msgs::Marker::ARROW;
00741         resetMarker.header.stamp = ros::Time::now();
00742         resetMarker.id = 1;
00743         vis_pub.publish(resetMarker);
00744         ros::spinOnce();
00745         mDebugHelperPtr->writeNoticeably(std::stringstream() << "Deleting markers for " << mIKVisualizationLastIterationCount << " iterations", DebugHelper::ROBOT_MODEL);
00746 
00747         for (unsigned int i = 1; i < mIKVisualizationLastIterationCount + 1; i++)
00748         {
00749             std::ostringstream converter;
00750             converter << i;
00751             std::string nsIterationVector = std::string("iterationVector") + converter.str();
00752             for (unsigned int j = 0; j < 3*(mPanAngleSamplingStepsPerIteration+1); j++)
00753             {
00754                 resetMarker.ns = nsIterationVector;
00755                 resetMarker.id = j;
00756                 resetMarker.header.stamp = ros::Time::now();
00757                 vis_pub.publish(resetMarker);
00758                 ros::spinOnce();
00759             }
00760         }
00761         ros::spinOnce();
00762         mIKVisualizationLastIterationCount = 0;
00763     }
00764 
00765     void MILDRobotModelWithExactIK::visualizeIKCameraTarget(Eigen::Vector3d &target_view_center_point, Eigen::Vector3d &target_camera_point)
00766     {
00767         Eigen::Vector4d color_green(0.0,1.0,0.0,1.0);
00768         visualizeIKArrowLarge(target_camera_point, target_view_center_point, color_green, "targetCameraVector", 0);
00769     }
00770 
00771     void MILDRobotModelWithExactIK::visualizeIKcalculation(Eigen::Vector3d &base_point, Eigen::Vector3d &base_orientation, Eigen::Vector3d &pan_joint_point, Eigen::Vector3d & pan_rotated_point, Eigen::Vector3d &tilt_base_point, Eigen::Vector3d &tilt_base_point_projected, Eigen::Vector3d &cam_point, Eigen::Vector3d &actual_view_center_point)
00772     {
00773         Eigen::Vector4d color_red(1.0,0.0,0.0,1.0);
00774         Eigen::Vector4d color_blue(0.0,0.0,1.0,1.0);
00775         base_orientation.normalize();
00776         Eigen::Vector3d base_point2 = base_point + base_orientation * 0.3;
00777         visualizeIKArrowLarge(cam_point, actual_view_center_point, color_blue, "camToActualViewCenterVector", 0);
00778         visualizeIKArrowSmall(tilt_base_point,cam_point, color_blue, "tiltToCamVector", 0);
00779         visualizeIKPoint(tilt_base_point_projected, color_red, "tiltBaseVectorProjected", 0);
00780         visualizeIKPoint(tilt_base_point, color_blue, "tiltBaseVector", 0);
00781         visualizeIKArrowSmall(pan_rotated_point,tilt_base_point, color_blue, "panToTiltVector", 0);
00782         visualizeIKPoint(pan_rotated_point, color_blue, "panBaseVector", 0);
00783         visualizeIKArrowSmall(base_point,pan_joint_point, color_blue, "baseToPanVector", 0);
00784         visualizeIKPoint(base_point, color_blue, "basePose", 0);
00785         visualizeIKArrowLarge(base_point, base_point2, color_blue, "basePose", 1);
00786     }
00787 
00788     void MILDRobotModelWithExactIK::visualizeCameraPoseCorrection(Eigen::Vector3d &base_point, Eigen::Vector3d &base_orientation, Eigen::Vector3d &pan_joint_point, Eigen::Vector3d & pan_rotated_point, Eigen::Vector3d &tilt_base_point, Eigen::Vector3d &cam_point, Eigen::Vector3d &actual_view_center_point)
00789     {
00790         Eigen::Vector4d color_red(1.0,0.0,0.0,1.0);
00791         base_orientation.normalize();
00792         Eigen::Vector3d base_point2 = base_point + base_orientation * 0.3;
00793         visualizeIKArrowLarge(cam_point, actual_view_center_point, color_red, "camToActualViewCenterVector_poseCorrection", 0);
00794         visualizeIKArrowSmall(tilt_base_point,cam_point, color_red, "tiltToCamVector_poseCorrection", 0);
00795         visualizeIKPoint(tilt_base_point, color_red, "tiltBaseVector_poseCorrection", 0);
00796         visualizeIKArrowSmall(pan_rotated_point,tilt_base_point, color_red, "panToTiltVector_poseCorrection", 0);
00797         visualizeIKPoint(pan_rotated_point, color_red, "panBaseVector_poseCorrection", 0);
00798         visualizeIKArrowSmall(base_point,pan_joint_point, color_red, "baseToPanVector_poseCorrection", 0);
00799         visualizeIKPoint(base_point, color_red, "basePose_poseCorrection", 0);
00800         visualizeIKArrowLarge(base_point, base_point2, color_red, "basePose_poseCorrection", 1);
00801     }
00802 
00803     void MILDRobotModelWithExactIK::visualizeIKPoint(Eigen::Vector3d &point, Eigen::Vector4d &colorRGBA, std::string ns, int id)
00804     {
00805         visualization_msgs::Marker pointMarker = visualization_msgs::Marker();
00806         pointMarker.header.stamp = ros::Time();
00807         pointMarker.header.frame_id = mFrameName_map;
00808         pointMarker.type = pointMarker.SPHERE;
00809         pointMarker.action = pointMarker.ADD;
00810         pointMarker.id = id;
00811         pointMarker.lifetime = ros::Duration();
00812         pointMarker.ns = ns;
00813         pointMarker.scale.x = 0.02;
00814         pointMarker.scale.y = 0.02;
00815         pointMarker.scale.z = 0.02;
00816         pointMarker.color.r = colorRGBA[0];
00817         pointMarker.color.g = colorRGBA[1];
00818         pointMarker.color.b = colorRGBA[2];
00819         pointMarker.color.a = colorRGBA[3];
00820         pointMarker.pose.position.x = point[0];
00821         pointMarker.pose.position.y = point[1];
00822         pointMarker.pose.position.z = point[2];
00823         vis_pub.publish(pointMarker);
00824         ros::spinOnce();
00825     }
00826 
00827     void MILDRobotModelWithExactIK::visualizeIKArrowSmall(Eigen::Vector3d &pointStart, Eigen::Vector3d &pointEnd, Eigen::Vector4d &colorRGBA, std::string ns, int id)
00828     {
00829         Eigen::Vector3d scaleParameters(0.005, 0.01, 0.01);
00830         visualizeIKArrow(pointStart, pointEnd, colorRGBA, ns, scaleParameters, id);
00831     }
00832 
00833     void MILDRobotModelWithExactIK::visualizeIKArrowLarge(Eigen::Vector3d &pointStart, Eigen::Vector3d &pointEnd, Eigen::Vector4d &colorRGBA, std::string ns, int id)
00834     {
00835         Eigen::Vector3d scaleParameters(0.02, 0.05, 0.1);
00836         visualizeIKArrow(pointStart, pointEnd, colorRGBA, ns, scaleParameters, id);
00837     }
00838 
00839     void MILDRobotModelWithExactIK::visualizeIKArrow(Eigen::Vector3d &pointStart, Eigen::Vector3d &pointEnd, Eigen::Vector4d &colorRGBA, std::string ns, Eigen::Vector3d &scaleParameters, int id)
00840     {
00841         geometry_msgs::Point point1, point2;
00842         visualization_msgs::Marker arrowMarker = visualization_msgs::Marker();
00843         arrowMarker.header.stamp = ros::Time();
00844         arrowMarker.header.frame_id = mFrameName_map;
00845         arrowMarker.type = arrowMarker.ARROW;
00846         arrowMarker.action = arrowMarker.ADD;
00847         arrowMarker.id = id;
00848         arrowMarker.lifetime = ros::Duration();
00849         arrowMarker.ns = ns;
00850         arrowMarker.scale.x = scaleParameters[0];     //d Shaft
00851         arrowMarker.scale.y = scaleParameters[1];    //d Head
00852         arrowMarker.scale.z = scaleParameters[2];     //l Head
00853         arrowMarker.color.r = colorRGBA[0];
00854         arrowMarker.color.g = colorRGBA[1];
00855         arrowMarker.color.b = colorRGBA[2];
00856         arrowMarker.color.a = colorRGBA[3];
00857         point1.x = pointStart[0];
00858         point1.y = pointStart[1];
00859         point1.z = pointStart[2];
00860         point2.x = pointEnd[0];
00861         point2.y = pointEnd[1];
00862         point2.z = pointEnd[2];
00863         arrowMarker.points.push_back(point1);
00864         arrowMarker.points.push_back(point2);
00865         vis_pub.publish(arrowMarker);
00866         ros::spinOnce();
00867     }
00868 
00869     double MILDRobotModelWithExactIK::getBaseAngleFromBaseFrame(Eigen::Affine3d &baseFrame)
00870     {
00871         Eigen::Vector3d xAxis(baseFrame(0,0), baseFrame(1,0), 0.0);
00872         Eigen::Vector3d yAxis(baseFrame(0,1), baseFrame(1,1), 0.0);
00873         xAxis.normalize();
00874         yAxis.normalize();
00875 
00876         if (yAxis[0] >= 0)
00877         {
00878             return acos(xAxis[0]);
00879         }
00880         else
00881         {
00882             return 2.0*M_PI - acos(xAxis[0]);
00883         }
00884     }
00885 }
00886 


asr_robot_model_services
Author(s): Aumann Florian, Borella Jocelyn, Heller Florian, Meißner Pascal, Schleicher Ralf, Stöckle Patrick, Stroh Daniel, Trautmann Jeremias, Walter Milena, Wittenbeck Valerij
autogenerated on Sat Jun 8 2019 18:24:52