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/MILDRobotModel.hpp"
00026 #include "robot_model_services/robot_model/impl/MILDRobotModelWithApproximatedIK.hpp"
00027 #include "robot_model_services/robot_model/impl/MILDRobotState.hpp"
00028 #include "robot_model_services/helper/MathHelper.hpp"
00029
00030 #include "nav_msgs/GetPlan.h"
00031 #include "geometry_msgs/PoseStamped.h"
00032 #include "geometry_msgs/Point.h"
00033
00034 #include "urdf/model.h"
00035 #include "urdf_model/joint.h"
00036 #include "tf/tf.h"
00037 #include "tf/transform_datatypes.h"
00038
00039 #include <kdl_parser/kdl_parser.hpp>
00040 #include <kdl/chain.hpp>
00041 #include <kdl/chainfksolver.hpp>
00042 #include <kdl/chainfksolverpos_recursive.hpp>
00043
00044 namespace robot_model_services {
00045 MILDRobotModelWithApproximatedIK::MILDRobotModelWithApproximatedIK() : MILDRobotModel() {
00046 mDebugHelperPtr = DebugHelper::getInstance();
00047 mDebugHelperPtr->write(std::stringstream() << "STARTING MILD ROBOT MODEL WITH APPROXIMATED IK", DebugHelper::ROBOT_MODEL);
00048
00049 navigationCostClient = n.serviceClient<nav_msgs::GetPlan>("/move_base/make_plan");
00050 double speedFactorPTU_,speedFactorBaseMove_,speedFactorBaseRot_;
00051 n.getParam("speedFactorPTU", speedFactorPTU_);
00052 n.getParam("speedFactorBaseMove", speedFactorBaseMove_);
00053 n.getParam("speedFactorBaseRot", speedFactorBaseRot_);
00054 mDebugHelperPtr->write(std::stringstream() << "speedFactorPTU: " << speedFactorPTU_, DebugHelper::PARAMETERS);
00055 mDebugHelperPtr->write(std::stringstream() << "speedFactorBaseMove: " << speedFactorBaseMove_, DebugHelper::PARAMETERS);
00056 mDebugHelperPtr->write(std::stringstream() << "speedFactorBaseRot: " << speedFactorBaseRot_, DebugHelper::PARAMETERS);
00057 speedFactorPTU = speedFactorPTU_;
00058 speedFactorBaseMove = speedFactorBaseMove_;
00059 speedFactorBaseRot = speedFactorBaseRot_;
00060 }
00061
00062 MILDRobotModelWithApproximatedIK::~MILDRobotModelWithApproximatedIK() {}
00063
00064
00065
00066
00067 RobotStatePtr MILDRobotModelWithApproximatedIK::calculateRobotState(const RobotStatePtr &sourceRobotState, const SimpleVector3 &position, const SimpleQuaternion &orientation)
00068 {
00069 mDebugHelperPtr->writeNoticeably("STARTING CALCULATE-ROBOT-STATE METHOD", DebugHelper::ROBOT_MODEL);
00070 MILDRobotStatePtr sourceMILDRobotState = boost::static_pointer_cast<MILDRobotState>(sourceRobotState);
00071 MILDRobotStatePtr targetMILDRobotState(new MILDRobotState());
00072
00073 SimpleVector3 visualAxis = MathHelper::getVisualAxis(orientation);
00074 SimpleSphereCoordinates sphereCoords = MathHelper::convertC2S(visualAxis);
00075 while (sphereCoords[2] < 0) { sphereCoords[2] += 2 * M_PI; }
00076 while (sphereCoords[2] > 2 * M_PI) { sphereCoords[2] -= 2 * M_PI; }
00077
00078 double phiMin = mPanLimits.get<0>();
00079 double phiMax = mPanLimits.get<1>();
00080 double currentPhi = sourceMILDRobotState->pan;
00081 double currentRho = sourceMILDRobotState->rotation;
00082
00083 mDebugHelperPtr->write(std::stringstream() << "Source robot state: (Pan: " << sourceMILDRobotState->pan
00084 << ", Tilt: " << sourceMILDRobotState->tilt
00085 << ", Rotation " << sourceMILDRobotState->rotation
00086 << ", X:" << sourceMILDRobotState->x
00087 << ", Y:" << sourceMILDRobotState->y << ")",
00088 DebugHelper::ROBOT_MODEL);
00089 mDebugHelperPtr->write(std::stringstream() << "Target View Position: " << position[0] << ", " << position[1] << ", " << position[2],
00090 DebugHelper::ROBOT_MODEL);
00091 mDebugHelperPtr->write(std::stringstream() << "Target View Orientation: " << orientation.w() << ", " << orientation.x() << ", " << orientation.y()<< ", " << orientation.z(),
00092 DebugHelper::ROBOT_MODEL);
00093
00094 double alpha = sphereCoords[2] - currentPhi - currentRho;
00095 alpha = alpha > M_PI ? alpha - 2 * M_PI : alpha;
00096 alpha = alpha < -M_PI ? alpha + 2 * M_PI : alpha;
00097
00098
00099 if (currentPhi < phiMin) {
00100 if (currentPhi < phiMin - 10.0) {
00101 ROS_WARN_STREAM("Initial Pan-Angle (" << currentPhi * (180/M_PI) << ") was too small.");
00102 } else {
00103 mDebugHelperPtr->write(std::stringstream() << "Initial Pan-Angle (" << currentPhi * (180/M_PI) << ") was too small.", DebugHelper::ROBOT_MODEL);
00104 }
00105 currentPhi = phiMin;
00106 }
00107 if (currentPhi > phiMax) {
00108 if (currentPhi > phiMax + 10.0) {
00109 ROS_WARN_STREAM("Initial Pan-Angle (" << currentPhi * (180/M_PI) << ") was too large.");
00110 } else {
00111 mDebugHelperPtr->write(std::stringstream() << "Initial Pan-Angle (" << currentPhi * (180/M_PI) << ") was too large.", DebugHelper::ROBOT_MODEL);
00112 }
00113 currentPhi = phiMax;
00114 }
00115
00116 glp_prob *lp;
00117
00118 int rows = 1;
00119 int cols = 4;
00120 int glIdx[1+cols*rows];
00121 int glColIdx[1+cols*rows];
00122 double glCoef[1+cols*rows];
00123
00124 lp = glp_create_prob();
00125 glp_set_prob_name(lp, "angle_prob");
00126 glp_set_obj_dir(lp, GLP_MIN);
00127
00128 glp_add_cols(lp, cols);
00129
00130 int colIdx = 1;
00131 glp_set_col_name(lp, colIdx, "x_pan+");
00132 double maxPanPlus = fabs(phiMax - currentPhi);
00133 glp_set_col_bnds(lp, colIdx, (maxPanPlus == 0.0 ? GLP_FX : GLP_DB), 0.0, maxPanPlus);
00134 glp_set_obj_coef(lp, colIdx, mOmegaPan);
00135
00136 colIdx++;
00137 glp_set_col_name(lp, colIdx, "x_pan-");
00138 double maxPanMinus = fabs(currentPhi - phiMin);
00139 glp_set_col_bnds(lp, colIdx, (maxPanMinus == 0.0 ? GLP_FX : GLP_DB), 0.0, maxPanMinus);
00140 glp_set_obj_coef(lp, colIdx, mOmegaPan);
00141
00142 colIdx++;
00143 glp_set_col_name(lp, colIdx, "x_rot+");
00144 glp_set_col_bnds(lp, colIdx, GLP_DB, 0, M_PI);
00145 glp_set_obj_coef(lp, colIdx, mOmegaRot);
00146
00147 colIdx++;
00148 glp_set_col_name(lp, colIdx, "x_rot-");
00149 glp_set_col_bnds(lp, colIdx, GLP_DB, 0.0, M_PI);
00150 glp_set_obj_coef(lp, colIdx, mOmegaRot);
00151
00152
00153 int rowIdx = 1;
00154 glp_add_rows(lp, rowIdx);
00155 glp_set_row_name(lp, rowIdx, "alpha");
00156 glp_set_row_bnds(lp, rowIdx, GLP_FX, alpha, alpha);
00157
00158
00159 glIdx[1] = 1; glColIdx[1] = 1; glCoef[1] = 1.0;
00160 glIdx[2] = 1; glColIdx[2] = 2; glCoef[2] = -1.0;
00161 glIdx[3] = 1; glColIdx[3] = 3; glCoef[3] = 1.0;
00162 glIdx[4] = 1; glColIdx[4] = 4; glCoef[4] = -1.0;
00163
00164
00165 glp_load_matrix(lp, 4, glIdx, glColIdx, glCoef);
00166
00167 glp_smcp *param = new glp_smcp();
00168 glp_init_smcp(param);
00169 param->msg_lev = GLP_MSG_OFF;
00170 glp_simplex(lp, param);
00171
00172 int statusCode = glp_get_status(lp);
00173 if (statusCode != GLP_OPT) {
00174 ROS_ERROR("No optimal solution found - inverse kinematics");
00175 }
00176
00177 double x_pan_plus = glp_get_col_prim(lp, 1);
00178 double x_pan_minus = glp_get_col_prim(lp, 2);
00179 double x_rot_plus = glp_get_col_prim(lp, 3);
00180 double x_rot_minus = glp_get_col_prim(lp, 4);
00181
00182
00183 glp_delete_prob(lp);
00184
00185
00186 targetMILDRobotState->pan = sourceMILDRobotState->pan + x_pan_plus - x_pan_minus;
00187
00188
00189 if (targetMILDRobotState->pan < phiMin) {
00190 if (targetMILDRobotState->pan < phiMin - 10.0) {
00191 ROS_WARN_STREAM("Calculated Pan-Angle (" << targetMILDRobotState->pan * (180/M_PI) << ") was too small.");
00192 } else {
00193 mDebugHelperPtr->write(std::stringstream() << "Calculated Pan-Angle (" << targetMILDRobotState->pan * (180/M_PI) << ") was too small.", DebugHelper::ROBOT_MODEL);
00194 }
00195 targetMILDRobotState->pan = phiMin;
00196 }
00197 if (targetMILDRobotState->pan > phiMax) {
00198 if (targetMILDRobotState->pan > phiMax + 10.0) {
00199 ROS_WARN_STREAM("Calculated Pan-Angle (" << targetMILDRobotState->pan * (180/M_PI) << ") was too large.");
00200 } else {
00201 mDebugHelperPtr->write(std::stringstream() << "Calculated Pan-Angle (" << targetMILDRobotState->pan * (180/M_PI) << ") was too large.", DebugHelper::ROBOT_MODEL);
00202 }
00203 targetMILDRobotState->pan = phiMax;
00204 }
00205
00206
00207 targetMILDRobotState->rotation = sourceMILDRobotState->rotation + x_rot_plus - x_rot_minus;
00208 while (targetMILDRobotState->rotation < 0) { targetMILDRobotState->rotation += 2 * M_PI; };
00209 while (targetMILDRobotState->rotation > 2 * M_PI) { targetMILDRobotState->rotation -= 2 * M_PI; };
00210
00211
00212 targetMILDRobotState->tilt = sphereCoords[1];
00213
00214
00215 targetMILDRobotState->x = position[0];
00216 targetMILDRobotState->y = position[1];
00217 mDebugHelperPtr->write(std::stringstream() << "Target state: (Pan: " << targetMILDRobotState->pan
00218 << ", Tilt: " << targetMILDRobotState->tilt
00219 << ", Rotation " << targetMILDRobotState->rotation
00220 << ", X:" << targetMILDRobotState->x
00221 << ", Y:" << targetMILDRobotState->y << ")",
00222 DebugHelper::ROBOT_MODEL);
00223 mDebugHelperPtr->writeNoticeably("ENDING CALCULATE-ROBOT-STATE METHOD", DebugHelper::ROBOT_MODEL);
00224 return targetMILDRobotState;
00225 }
00226 }
00227