00001
00020 #include "robot_model_services/helper/MathHelper.hpp"
00021
00022 namespace robot_model_services {
00023
00024 boost::mt19937& MathHelper::getRandomnessGenerator() {
00025 static boost::mt19937 gen(5);
00026 return gen;
00027 }
00028
00029 SimpleSphereCoordinates MathHelper::convertC2S(const SimpleVector3 &cartesian) {
00030 SimpleSphereCoordinates ssc;
00031 convertC2S(cartesian, ssc);
00032 return ssc;
00033 }
00034
00035 void MathHelper::convertC2S(const SimpleVector3 &cartesian, SimpleSphereCoordinates &sphere) {
00036 sphere[0] = cartesian.lpNorm<2>();
00037 sphere[1] = asin(cartesian[2]);
00038 sphere[2] = atan2(cartesian[1], cartesian[0]);
00039 }
00040
00041 SimpleVector3 MathHelper::convertS2C(const SimpleSphereCoordinates &sphere) {
00042 SimpleVector3 cartesian;
00043 convertS2C(sphere, cartesian);
00044 return cartesian;
00045 }
00046
00047 void MathHelper::convertS2C(const SimpleSphereCoordinates &sphere, SimpleVector3 &cartesian) {
00048 cartesian[0] = sphere[0] * cos(sphere[1]) * cos(sphere[2]);
00049 cartesian[1] = sphere[0] * cos(sphere[1]) * sin(sphere[2]);
00050 cartesian[2] = sphere[0] * sin(sphere[1]);
00051 }
00052
00053 SimpleVector3 MathHelper::getVisualAxis(const SimpleQuaternion &orientation) {
00054 SimpleVector3 resultAxis;
00055 getVisualAxis(orientation, resultAxis);
00056 return resultAxis;
00057 }
00058
00059 void MathHelper::getVisualAxis(const SimpleQuaternion &orientation, SimpleVector3 &resultAxis) {
00060 resultAxis = orientation.toRotationMatrix() * SimpleVector3::UnitX();
00061 }
00062
00063 double MathHelper::getSignum(const double &value) {
00064 return (value == 0 ? 0.0 : (value < 0 ? -1.0 : 1.0));
00065 }
00066
00067 SimpleVector3 MathHelper::getProjection(const std::size_t &idx, const SimpleVector3 &X) {
00068 return SimpleVector3((idx == 0 ? 0 : X[0]), (idx == 1 ? 0 : X[1]), (idx == 2 ? 0 : X[2]));
00069 }
00070
00071 Precision MathHelper::getCosinus(const SimpleVector3 &X, const SimpleVector3 &Y) {
00072 Precision xNorm = X.lpNorm<2>();
00073 Precision yNorm = Y.lpNorm<2>();
00074
00075 if (xNorm == 0 || yNorm == 0) {
00076 return 0.0;
00077 }
00078 return X.dot(Y) / xNorm / yNorm;
00079 }
00080
00081 Precision MathHelper::getAngle(const SimpleVector3 &X, const SimpleVector3 &Y) {
00082 float cosinus = getCosinus(X, Y);
00083 float angle = acos(cosinus);
00084 return angle;
00085 }
00086
00087 Precision MathHelper::getMinimumAngleDifference(const Precision &firstAngle, const Precision &secondAngle) {
00088 Precision angleDiff = fabs(firstAngle - secondAngle);
00089 return fmin(angleDiff, 2 * M_PI - angleDiff);
00090 }
00091
00092 int MathHelper::getRandomInteger(const int &min, const int &max) {
00093 boost::uniform_int<> uniform(min, max);
00094 boost::variate_generator<boost::mt19937&, boost::uniform_int<> > random(getRandomnessGenerator(), uniform);
00095 return random();
00096 }
00097
00098 Precision MathHelper::getRandomNumber(const Precision &mean, const Precision &standardDeviation) {
00099 boost::normal_distribution<Precision> uniform(mean, standardDeviation);
00100 boost::variate_generator<boost::mt19937&, boost::normal_distribution<Precision> > random(getRandomnessGenerator(), uniform);
00101 return random();
00102 }
00103
00104 SimpleVectorX MathHelper::getRandomVector(const SimpleVectorX &mean, const SimpleVectorX &standardDeviation) {
00105 SimpleVectorX result(mean.rows());
00106
00107 for (int i = 0; i < mean.rows(); i++) {
00108 result[i] = getRandomNumber(mean[i], standardDeviation[i]);
00109 }
00110 return result;
00111 }
00112
00113 SimpleQuaternion MathHelper::getRandomQuaternion() {
00114 SimpleVector3 randomAngles = getRandomVector(SimpleVector3(0.0, 0.0, 0.0), SimpleVector3(2 * M_PI, 2 * M_PI, 1.0));
00115 return getQuaternionByAngles(randomAngles[0], randomAngles[1], 0);
00116 }
00117
00118 SimpleQuaternion MathHelper::getQuaternionByAngles(const Precision &heading, const Precision &attitude, const Precision &bank) {
00119 double c1 = cos(heading / 2);
00120 double c2 = cos(attitude / 2);
00121 double c3 = cos(bank / 2);
00122 double s1 = sin(heading / 2);
00123 double s2 = sin(attitude / 2);
00124 double s3 = sin(bank / 2);
00125
00126 SimpleQuaternion quatHeading(c1, 0.0, 0.0, s1);
00127 SimpleQuaternion quatAttitude(c2, 0.0, s2, 0.0);
00128 SimpleQuaternion quatBank(c3, s3, 0.0, 0.0);
00129
00130
00131 SimpleQuaternion result = quatHeading * quatAttitude * quatBank;
00132
00133 return result.normalized();
00134 }
00135
00136 SimpleQuaternionCollectionPtr MathHelper::getOrientationsOnUnitSphere(const int &numberOfPoints) {
00137 SimpleQuaternionCollectionPtr oritentationCollectionPtr(new SimpleQuaternionCollection());
00138
00139
00140 float dlong = M_PI * (3.0 - sqrt(5.0));
00141 float dz = 2.0 / numberOfPoints;
00142 float longitude = 0.0;
00143 float z = 1.0 - dz / 2.0;
00144
00145 for (int k = 0; k < numberOfPoints; k += 1) {
00146 float r = sqrt(1.0 - pow(z, 2));
00147
00148 SimpleVector3 point;
00149 point[0] = cos(longitude) * r;
00150 point[1] = sin(longitude) * r;
00151 point[2] = z;
00152
00153 SimpleSphereCoordinates sphereCoords = convertC2S(point);
00154 SimpleQuaternion orientation = MathHelper::getQuaternionByAngles(sphereCoords[2], sphereCoords[1], 0.0);
00155 oritentationCollectionPtr->push_back(orientation);
00156
00157 z -= dz;
00158 longitude += dlong;
00159 if (z < -1) {
00160 break;
00161 }
00162 }
00163
00164 return oritentationCollectionPtr;
00165 }
00166
00167
00168 double MathHelper::radToDeg(double input) {
00169 return fmod(input / M_PI * 180.0, 360);
00170 }
00171
00172 double MathHelper::degToRad(double input) {
00173 return fmod(input / 180.0 * M_PI, 2 * M_PI);
00174 }
00175
00176 double MathHelper::getDotProduct(SimpleVector3 v1, SimpleVector3 v2)
00177 {
00178 return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
00179 }
00180 }