Go to the documentation of this file.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
00031
00032
00033
00034
00035
00036
00037
00038 #include <moveit/robot_model/floating_joint_model.h>
00039 #include <boost/math/constants/constants.hpp>
00040 #include <console_bridge/console.h>
00041 #include <limits>
00042 #include <cmath>
00043
00044 moveit::core::FloatingJointModel::FloatingJointModel(const std::string& name)
00045 : JointModel(name), angular_distance_weight_(1.0)
00046 {
00047 type_ = FLOATING;
00048 local_variable_names_.push_back("trans_x");
00049 local_variable_names_.push_back("trans_y");
00050 local_variable_names_.push_back("trans_z");
00051 local_variable_names_.push_back("rot_x");
00052 local_variable_names_.push_back("rot_y");
00053 local_variable_names_.push_back("rot_z");
00054 local_variable_names_.push_back("rot_w");
00055 for (int i = 0; i < 7; ++i)
00056 {
00057 variable_names_.push_back(name_ + "/" + local_variable_names_[i]);
00058 variable_index_map_[variable_names_.back()] = i;
00059 }
00060
00061 variable_bounds_.resize(7);
00062
00063 variable_bounds_[0].position_bounded_ = true;
00064 variable_bounds_[1].position_bounded_ = true;
00065 variable_bounds_[2].position_bounded_ = true;
00066 variable_bounds_[3].position_bounded_ = true;
00067 variable_bounds_[4].position_bounded_ = true;
00068 variable_bounds_[5].position_bounded_ = true;
00069 variable_bounds_[6].position_bounded_ = true;
00070
00071 variable_bounds_[0].min_position_ = -std::numeric_limits<double>::infinity();
00072 variable_bounds_[0].max_position_ = std::numeric_limits<double>::infinity();
00073 variable_bounds_[1].min_position_ = -std::numeric_limits<double>::infinity();
00074 variable_bounds_[1].max_position_ = std::numeric_limits<double>::infinity();
00075 variable_bounds_[2].min_position_ = -std::numeric_limits<double>::infinity();
00076 variable_bounds_[2].max_position_ = std::numeric_limits<double>::infinity();
00077 variable_bounds_[3].min_position_ = -1.0;
00078 variable_bounds_[3].max_position_ = 1.0;
00079 variable_bounds_[4].min_position_ = -1.0;
00080 variable_bounds_[4].max_position_ = 1.0;
00081 variable_bounds_[5].min_position_ = -1.0;
00082 variable_bounds_[5].max_position_ = 1.0;
00083 variable_bounds_[6].min_position_ = -1.0;
00084 variable_bounds_[6].max_position_ = 1.0;
00085
00086 computeVariableBoundsMsg();
00087 }
00088
00089 double moveit::core::FloatingJointModel::getMaximumExtent(const Bounds& other_bounds) const
00090 {
00091 double dx = other_bounds[0].max_position_ - other_bounds[0].min_position_;
00092 double dy = other_bounds[1].max_position_ - other_bounds[1].min_position_;
00093 double dz = other_bounds[2].max_position_ - other_bounds[2].min_position_;
00094 return sqrt(dx * dx + dy * dy + dz * dz) + boost::math::constants::pi<double>() * 0.5 * angular_distance_weight_;
00095 }
00096
00097 double moveit::core::FloatingJointModel::distance(const double* values1, const double* values2) const
00098 {
00099 return distanceTranslation(values1, values2) + angular_distance_weight_ * distanceRotation(values1, values2);
00100 }
00101
00102 double moveit::core::FloatingJointModel::distanceTranslation(const double* values1, const double* values2) const
00103 {
00104 double dx = values1[0] - values2[0];
00105 double dy = values1[1] - values2[1];
00106 double dz = values1[2] - values2[2];
00107 return sqrt(dx * dx + dy * dy + dz * dz);
00108 }
00109
00110 double moveit::core::FloatingJointModel::distanceRotation(const double* values1, const double* values2) const
00111 {
00112 double dq =
00113 fabs(values1[3] * values2[3] + values1[4] * values2[4] + values1[5] * values2[5] + values1[6] * values2[6]);
00114 if (dq + std::numeric_limits<double>::epsilon() >= 1.0)
00115 return 0.0;
00116 else
00117 return acos(dq);
00118 }
00119
00120 void moveit::core::FloatingJointModel::interpolate(const double* from, const double* to, const double t,
00121 double* state) const
00122 {
00123
00124 state[0] = from[0] + (to[0] - from[0]) * t;
00125 state[1] = from[1] + (to[1] - from[1]) * t;
00126 state[2] = from[2] + (to[2] - from[2]) * t;
00127
00128 double dq = fabs(from[3] * to[3] + from[4] * to[4] + from[5] * to[5] + from[6] * to[6]);
00129 double theta = (dq + std::numeric_limits<double>::epsilon() >= 1.0) ? 0.0 : acos(dq);
00130 if (theta > std::numeric_limits<double>::epsilon())
00131 {
00132 double d = 1.0 / sin(theta);
00133 double s0 = sin((1.0 - t) * theta);
00134 double s1 = sin(t * theta);
00135 if (dq < 0)
00136 s1 = -s1;
00137 state[3] = (from[3] * s0 + to[3] * s1) * d;
00138 state[4] = (from[4] * s0 + to[4] * s1) * d;
00139 state[5] = (from[5] * s0 + to[5] * s1) * d;
00140 state[6] = (from[6] * s0 + to[6] * s1) * d;
00141 }
00142 else
00143 {
00144 state[3] = from[3];
00145 state[4] = from[4];
00146 state[5] = from[5];
00147 state[6] = from[6];
00148 }
00149 }
00150
00151 bool moveit::core::FloatingJointModel::satisfiesPositionBounds(const double* values, const Bounds& bounds,
00152 double margin) const
00153 {
00154 if (values[0] < bounds[0].min_position_ - margin || values[0] > bounds[0].max_position_ + margin)
00155 return false;
00156 if (values[1] < bounds[1].min_position_ - margin || values[1] > bounds[1].max_position_ + margin)
00157 return false;
00158 if (values[2] < bounds[2].min_position_ - margin || values[2] > bounds[2].max_position_ + margin)
00159 return false;
00160 double normSqr = values[3] * values[3] + values[4] * values[4] + values[5] * values[5] + values[6] * values[6];
00161 if (fabs(normSqr - 1.0) > std::numeric_limits<float>::epsilon() * 10.0)
00162 return false;
00163 return true;
00164 }
00165
00166 bool moveit::core::FloatingJointModel::normalizeRotation(double* values) const
00167 {
00168
00169 double normSqr = values[3] * values[3] + values[4] * values[4] + values[5] * values[5] + values[6] * values[6];
00170 if (fabs(normSqr - 1.0) > std::numeric_limits<double>::epsilon() * 100.0)
00171 {
00172 double norm = sqrt(normSqr);
00173 if (norm < std::numeric_limits<double>::epsilon() * 100.0)
00174 {
00175 logWarn("Quaternion is zero in RobotState representation. Setting to identity");
00176 values[3] = 0.0;
00177 values[4] = 0.0;
00178 values[5] = 0.0;
00179 values[6] = 1.0;
00180 }
00181 else
00182 {
00183 values[3] /= norm;
00184 values[4] /= norm;
00185 values[5] /= norm;
00186 values[6] /= norm;
00187 }
00188 return true;
00189 }
00190 else
00191 return false;
00192 }
00193
00194 unsigned int moveit::core::FloatingJointModel::getStateSpaceDimension() const
00195 {
00196 return 6;
00197 }
00198
00199 bool moveit::core::FloatingJointModel::enforcePositionBounds(double* values, const Bounds& bounds) const
00200 {
00201 bool result = normalizeRotation(values);
00202 for (unsigned int i = 0; i < 3; ++i)
00203 {
00204 if (values[i] < bounds[i].min_position_)
00205 {
00206 values[i] = bounds[i].min_position_;
00207 result = true;
00208 }
00209 else if (values[i] > bounds[i].max_position_)
00210 {
00211 values[i] = bounds[i].max_position_;
00212 result = true;
00213 }
00214 }
00215 return result;
00216 }
00217
00218 void moveit::core::FloatingJointModel::computeTransform(const double* joint_values, Eigen::Affine3d& transf) const
00219 {
00220 transf = Eigen::Affine3d(
00221 Eigen::Translation3d(joint_values[0], joint_values[1], joint_values[2]) *
00222 Eigen::Quaterniond(joint_values[6], joint_values[3], joint_values[4], joint_values[5]).toRotationMatrix());
00223 }
00224
00225 void moveit::core::FloatingJointModel::computeVariablePositions(const Eigen::Affine3d& transf,
00226 double* joint_values) const
00227 {
00228 joint_values[0] = transf.translation().x();
00229 joint_values[1] = transf.translation().y();
00230 joint_values[2] = transf.translation().z();
00231 Eigen::Quaterniond q(transf.rotation());
00232 joint_values[3] = q.x();
00233 joint_values[4] = q.y();
00234 joint_values[5] = q.z();
00235 joint_values[6] = q.w();
00236 }
00237
00238 void moveit::core::FloatingJointModel::getVariableDefaultPositions(double* values, const Bounds& bounds) const
00239 {
00240 for (unsigned int i = 0; i < 3; ++i)
00241 {
00242
00243 if (bounds[i].min_position_ <= 0.0 && bounds[i].max_position_ >= 0.0)
00244 values[i] = 0.0;
00245 else
00246 values[i] = (bounds[i].min_position_ + bounds[i].max_position_) / 2.0;
00247 }
00248
00249 values[3] = 0.0;
00250 values[4] = 0.0;
00251 values[5] = 0.0;
00252 values[6] = 1.0;
00253 }
00254
00255 void moveit::core::FloatingJointModel::getVariableRandomPositions(random_numbers::RandomNumberGenerator& rng,
00256 double* values, const Bounds& bounds) const
00257 {
00258 if (bounds[0].max_position_ >= std::numeric_limits<double>::infinity() ||
00259 bounds[0].min_position_ <= -std::numeric_limits<double>::infinity())
00260 values[0] = 0.0;
00261 else
00262 values[0] = rng.uniformReal(bounds[0].min_position_, bounds[0].max_position_);
00263 if (bounds[1].max_position_ >= std::numeric_limits<double>::infinity() ||
00264 bounds[1].min_position_ <= -std::numeric_limits<double>::infinity())
00265 values[1] = 0.0;
00266 else
00267 values[1] = rng.uniformReal(bounds[1].min_position_, bounds[1].max_position_);
00268 if (bounds[2].max_position_ >= std::numeric_limits<double>::infinity() ||
00269 bounds[2].min_position_ <= -std::numeric_limits<double>::infinity())
00270 values[2] = 0.0;
00271 else
00272 values[2] = rng.uniformReal(bounds[2].min_position_, bounds[2].max_position_);
00273
00274 double q[4];
00275 rng.quaternion(q);
00276 values[3] = q[0];
00277 values[4] = q[1];
00278 values[5] = q[2];
00279 values[6] = q[3];
00280 }
00281
00282 void moveit::core::FloatingJointModel::getVariableRandomPositionsNearBy(random_numbers::RandomNumberGenerator& rng,
00283 double* values, const Bounds& bounds,
00284 const double* near, const double distance) const
00285 {
00286 if (bounds[0].max_position_ >= std::numeric_limits<double>::infinity() ||
00287 bounds[0].min_position_ <= -std::numeric_limits<double>::infinity())
00288 values[0] = 0.0;
00289 else
00290 values[0] = rng.uniformReal(std::max(bounds[0].min_position_, near[0] - distance),
00291 std::min(bounds[0].max_position_, near[0] + distance));
00292 if (bounds[1].max_position_ >= std::numeric_limits<double>::infinity() ||
00293 bounds[1].min_position_ <= -std::numeric_limits<double>::infinity())
00294 values[1] = 0.0;
00295 else
00296 values[1] = rng.uniformReal(std::max(bounds[1].min_position_, near[1] - distance),
00297 std::min(bounds[1].max_position_, near[1] + distance));
00298 if (bounds[2].max_position_ >= std::numeric_limits<double>::infinity() ||
00299 bounds[2].min_position_ <= -std::numeric_limits<double>::infinity())
00300 values[2] = 0.0;
00301 else
00302 values[2] = rng.uniformReal(std::max(bounds[2].min_position_, near[2] - distance),
00303 std::min(bounds[2].max_position_, near[2] + distance));
00304
00305 double da = angular_distance_weight_ * distance;
00306 if (da >= .25 * boost::math::constants::pi<double>())
00307 {
00308 double q[4];
00309 rng.quaternion(q);
00310 values[3] = q[0];
00311 values[4] = q[1];
00312 values[5] = q[2];
00313 values[6] = q[3];
00314 }
00315 else
00316 {
00317
00318
00319 double ax = rng.gaussian01();
00320 double ay = rng.gaussian01();
00321 double az = rng.gaussian01();
00322 double angle = 2.0 * pow(rng.uniform01(), 1.0 / 3.0) * da;
00323
00324 double q[4];
00325 double norm = sqrt(ax * ax + ay * ay + az * az);
00326 if (norm < 1e-6)
00327 {
00328 q[0] = q[1] = q[2] = 0.0;
00329 q[3] = 1.0;
00330 }
00331 else
00332 {
00333 double s = sin(angle / 2.0);
00334 q[0] = s * ax / norm;
00335 q[1] = s * ay / norm;
00336 q[2] = s * az / norm;
00337 q[3] = cos(angle / 2.0);
00338 }
00339
00340 values[3] = near[6] * q[0] + near[3] * q[3] + near[4] * q[2] - near[5] * q[1];
00341 values[4] = near[6] * q[1] + near[4] * q[3] + near[5] * q[0] - near[3] * q[2];
00342 values[5] = near[6] * q[2] + near[5] * q[3] + near[3] * q[1] - near[4] * q[0];
00343 values[6] = near[6] * q[3] - near[3] * q[0] - near[4] * q[1] - near[5] * q[2];
00344 }
00345 }