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
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include <youbot_driver/base-kinematic/FourSwedishWheelOmniBaseKinematic.hpp>
00052 namespace youbot
00053 {
00054
00055 FourSwedishWheelOmniBaseKinematic::FourSwedishWheelOmniBaseKinematic()
00056 {
00057
00058 this->lastWheelPositionInitialized = false;
00059
00060 }
00061
00062 FourSwedishWheelOmniBaseKinematic::~FourSwedishWheelOmniBaseKinematic()
00063 {
00064
00065
00066 }
00067
00073 void FourSwedishWheelOmniBaseKinematic::cartesianVelocityToWheelVelocities(
00074 const quantity<si::velocity>& longitudinalVelocity, const quantity<si::velocity>& transversalVelocity,
00075 const quantity<si::angular_velocity>& angularVelocity, std::vector<quantity<angular_velocity> >& wheelVelocities)
00076 {
00077
00078 quantity<angular_velocity> RadPerSec_FromX;
00079 quantity<angular_velocity> RadPerSec_FromY;
00080 quantity<angular_velocity> RadPerSec_FromTheta;
00081 wheelVelocities.assign(4, RadPerSec_FromX);
00082
00083 if (config.wheelRadius.value() == 0 || config.rotationRatio == 0 || config.slideRatio == 0)
00084 {
00085 throw std::out_of_range("The wheelRadius, RotationRatio or the SlideRatio are not allowed to be zero");
00086 }
00087
00088
00089 RadPerSec_FromX = longitudinalVelocity.value() / config.wheelRadius.value() * radian_per_second;
00090 RadPerSec_FromY = transversalVelocity.value() / (config.wheelRadius.value() * config.slideRatio) * radian_per_second;
00091
00092
00093 RadPerSec_FromTheta = ((config.lengthBetweenFrontAndRearWheels + config.lengthBetweenFrontWheels)
00094 / (2.0 * config.wheelRadius)) * angularVelocity;
00095
00096 wheelVelocities[0] = -RadPerSec_FromX + RadPerSec_FromY + RadPerSec_FromTheta;
00097 wheelVelocities[1] = RadPerSec_FromX + RadPerSec_FromY + RadPerSec_FromTheta;
00098 wheelVelocities[2] = -RadPerSec_FromX - RadPerSec_FromY + RadPerSec_FromTheta;
00099 wheelVelocities[3] = RadPerSec_FromX - RadPerSec_FromY + RadPerSec_FromTheta;
00100
00101 return;
00102
00103
00104 }
00105
00111 void FourSwedishWheelOmniBaseKinematic::wheelVelocitiesToCartesianVelocity(
00112 const std::vector<quantity<angular_velocity> >& wheelVelocities, quantity<si::velocity>& longitudinalVelocity,
00113 quantity<si::velocity>& transversalVelocity, quantity<angular_velocity>& angularVelocity)
00114 {
00115
00116
00117 if (wheelVelocities.size() < 4)
00118 throw std::out_of_range("To less wheel velocities");
00119
00120 if (config.lengthBetweenFrontAndRearWheels.value() == 0 || config.lengthBetweenFrontWheels.value() == 0)
00121 {
00122 throw std::out_of_range(
00123 "The lengthBetweenFrontAndRearWheels or the lengthBetweenFrontWheels are not allowed to be zero");
00124 }
00125
00126 quantity<si::length> wheel_radius_per4 = config.wheelRadius / 4.0;
00127
00128 quantity<si::length> geom_factor = (config.lengthBetweenFrontAndRearWheels / 2.0)
00129 + (config.lengthBetweenFrontWheels / 2.0);
00130
00131 longitudinalVelocity = (-wheelVelocities[0] + wheelVelocities[1] - wheelVelocities[2] + wheelVelocities[3]).value()
00132 * wheel_radius_per4.value() * meter_per_second;
00133 transversalVelocity = (wheelVelocities[0] + wheelVelocities[1] - wheelVelocities[2] - wheelVelocities[3]).value()
00134 * wheel_radius_per4.value() * meter_per_second;
00135 angularVelocity = (wheelVelocities[0] + wheelVelocities[1] + wheelVelocities[2] + wheelVelocities[3])
00136 * (wheel_radius_per4 / geom_factor).value();
00137
00138 return;
00139
00140 }
00141
00147 void FourSwedishWheelOmniBaseKinematic::wheelPositionsToCartesianPosition(
00148 const std::vector<quantity<plane_angle> >& wheelPositions, quantity<si::length>& longitudinalPosition,
00149 quantity<si::length>& transversalPosition, quantity<plane_angle>& orientation)
00150 {
00151
00152
00153 if (wheelPositions.size() < 4)
00154 throw std::out_of_range("To less wheel positions");
00155
00156 if (config.lengthBetweenFrontAndRearWheels.value() == 0 || config.lengthBetweenFrontWheels.value() == 0)
00157 {
00158 throw std::out_of_range(
00159 "The lengthBetweenFrontAndRearWheels or the lengthBetweenFrontWheels are not allowed to be zero");
00160 }
00161
00162 if (this->lastWheelPositionInitialized == false)
00163 {
00164 lastWheelPositions = wheelPositions;
00165 longitudinalPos = 0 * meter;
00166 transversalPos = 0 * meter;
00167 angle = 0 * radian;
00168 this->lastWheelPositionInitialized = true;
00169 }
00170
00171 quantity<si::length> deltaLongitudinalPos;
00172 quantity<si::length> deltaTransversalPos;
00173
00174 quantity<si::length> wheel_radius_per4 = config.wheelRadius / 4.0;
00175
00176 quantity<si::length> geom_factor = (config.lengthBetweenFrontAndRearWheels / 2.0)
00177 + (config.lengthBetweenFrontWheels / 2.0);
00178
00179 quantity<plane_angle> deltaPositionW1 = (wheelPositions[0] - lastWheelPositions[0]);
00180 quantity<plane_angle> deltaPositionW2 = (wheelPositions[1] - lastWheelPositions[1]);
00181 quantity<plane_angle> deltaPositionW3 = (wheelPositions[2] - lastWheelPositions[2]);
00182 quantity<plane_angle> deltaPositionW4 = (wheelPositions[3] - lastWheelPositions[3]);
00183 lastWheelPositions[0] = wheelPositions[0];
00184 lastWheelPositions[1] = wheelPositions[1];
00185 lastWheelPositions[2] = wheelPositions[2];
00186 lastWheelPositions[3] = wheelPositions[3];
00187
00188 deltaLongitudinalPos = (-deltaPositionW1 + deltaPositionW2 - deltaPositionW3 + deltaPositionW4).value()
00189 * wheel_radius_per4.value() * meter;
00190 deltaTransversalPos = (deltaPositionW1 + deltaPositionW2 - deltaPositionW3 - deltaPositionW4).value()
00191 * wheel_radius_per4.value() * meter;
00192 angle += (deltaPositionW1 + deltaPositionW2 + deltaPositionW3 + deltaPositionW4)
00193 * (wheel_radius_per4 / geom_factor).value();
00194
00195 longitudinalPos += deltaLongitudinalPos * cos(angle) - deltaTransversalPos * sin(angle);
00196 transversalPos += deltaLongitudinalPos * sin(angle) + deltaTransversalPos * cos(angle);
00197
00198 longitudinalPosition = longitudinalPos;
00199 transversalPosition = transversalPos;
00200 orientation = angle;
00201
00202 return;
00203
00204 }
00205
00211 void FourSwedishWheelOmniBaseKinematic::cartesianPositionToWheelPositions(
00212 const quantity<si::length>& longitudinalPosition, const quantity<si::length>& transversalPosition,
00213 const quantity<plane_angle>& orientation, std::vector<quantity<plane_angle> >& wheelPositions)
00214 {
00215
00216
00217 quantity<plane_angle> Rad_FromX;
00218 quantity<plane_angle> Rad_FromY;
00219 quantity<plane_angle> Rad_FromTheta;
00220 wheelPositions.assign(4, Rad_FromX);
00221
00222 if (config.wheelRadius.value() == 0 || config.rotationRatio == 0 || config.slideRatio == 0)
00223 {
00224 throw std::out_of_range("The wheelRadius, RotationRatio or the SlideRatio are not allowed to be zero");
00225 }
00226
00227
00228 Rad_FromX = longitudinalPosition.value() / config.wheelRadius.value() * radian;
00229 Rad_FromY = transversalPosition.value() / (config.wheelRadius.value() * config.slideRatio) * radian;
00230
00231
00232 Rad_FromTheta = ((config.lengthBetweenFrontAndRearWheels + config.lengthBetweenFrontWheels)
00233 / (2.0 * config.wheelRadius)) * orientation;
00234
00235 wheelPositions[0] = -Rad_FromX + Rad_FromY + Rad_FromTheta;
00236 wheelPositions[1] = Rad_FromX + Rad_FromY + Rad_FromTheta;
00237 wheelPositions[2] = -Rad_FromX - Rad_FromY + Rad_FromTheta;
00238 wheelPositions[3] = Rad_FromX - Rad_FromY + Rad_FromTheta;
00239
00240 return;
00241
00242
00243 }
00244
00245 void FourSwedishWheelOmniBaseKinematic::setConfiguration(
00246 const FourSwedishWheelOmniBaseKinematicConfiguration& configuration)
00247 {
00248
00249 this->config = configuration;
00250
00251 }
00252
00253 void FourSwedishWheelOmniBaseKinematic::getConfiguration(
00254 FourSwedishWheelOmniBaseKinematicConfiguration& configuration) const
00255 {
00256
00257 configuration = this->config;
00258
00259 }
00260
00261 }