Add covariance info to Pose and Vel
Fix getMode bug
This commit is contained in:
parent
1133a0e4bb
commit
82b01e4057
5 changed files with 149 additions and 13 deletions
122
src/create.cpp
122
src/create.cpp
|
@ -12,6 +12,8 @@
|
|||
|
||||
namespace create {
|
||||
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
|
||||
// TODO: Handle SIGINT to do clean disconnect
|
||||
|
||||
void Create::init() {
|
||||
|
@ -33,6 +35,7 @@ namespace create {
|
|||
vel.x = 0;
|
||||
vel.y = 0;
|
||||
vel.yaw = 0;
|
||||
poseCovar = Matrix(3, 3);
|
||||
data = boost::shared_ptr<Data>(new Data(model));
|
||||
serial = boost::make_shared<Serial>(data);
|
||||
}
|
||||
|
@ -50,6 +53,30 @@ namespace create {
|
|||
disconnect();
|
||||
}
|
||||
|
||||
Create::Matrix Create::addMatrices(const Matrix &A, const Matrix &B) const {
|
||||
int rows = A.size1();
|
||||
int cols = A.size2();
|
||||
|
||||
assert(rows == B.size1());
|
||||
assert(cols == B.size2());
|
||||
|
||||
Matrix C(rows, cols);
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
const float a = A(i, j);
|
||||
const float b = B(i, j);
|
||||
if (util::willFloatOverflow(a, b)) {
|
||||
// If overflow, set to float min or max depending on direction of overflow
|
||||
C(i, j) = (a < 0.0) ? std::numeric_limits<float>::min() : std::numeric_limits<float>::max();
|
||||
}
|
||||
else {
|
||||
C(i, j) = a + b;
|
||||
}
|
||||
}
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
void Create::onData() {
|
||||
if (firstOnData) {
|
||||
if (model == CREATE_2) {
|
||||
|
@ -64,7 +91,7 @@ namespace create {
|
|||
// Get current time
|
||||
util::timestamp_t curTime = util::getTimestamp();
|
||||
float dt = (curTime - prevOnDataTime) / 1000000.0;
|
||||
float deltaDist, deltaX, deltaY, deltaYaw;
|
||||
float deltaDist, deltaX, deltaY, deltaYaw, leftWheelDist, rightWheelDist;
|
||||
if (model == CREATE_1) {
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Angle returned is NOT correct if your robot is using older firmware: *
|
||||
|
@ -75,6 +102,9 @@ namespace create {
|
|||
deltaYaw = ((int16_t) GET_DATA(ID_ANGLE)) * (util::PI / 180.0); // D2R
|
||||
deltaX = deltaDist * cos( util::normalizeAngle(pose.yaw + deltaYaw) );
|
||||
deltaY = -deltaDist * sin( util::normalizeAngle(pose.yaw + deltaYaw) );
|
||||
leftWheelDist = deltaDist / 2.0;
|
||||
rightWheelDist = leftWheelDist;
|
||||
|
||||
}
|
||||
else if (model == CREATE_2) {
|
||||
// Get cumulative ticks (wraps around at 65535)
|
||||
|
@ -95,10 +125,10 @@ namespace create {
|
|||
}
|
||||
|
||||
// Compute distance travelled by each wheel
|
||||
float leftWheelDist = (ticksLeft / util::CREATE_2_TICKS_PER_REV)
|
||||
* util::CREATE_2_WHEEL_DIAMETER * util::PI;
|
||||
float rightWheelDist = (ticksRight / util::CREATE_2_TICKS_PER_REV)
|
||||
* util::CREATE_2_WHEEL_DIAMETER * util::PI;
|
||||
leftWheelDist = (ticksLeft / util::CREATE_2_TICKS_PER_REV)
|
||||
* util::CREATE_2_WHEEL_DIAMETER * util::PI;
|
||||
rightWheelDist = (ticksRight / util::CREATE_2_TICKS_PER_REV)
|
||||
* util::CREATE_2_WHEEL_DIAMETER * util::PI;
|
||||
|
||||
float wheelDistDiff = rightWheelDist - leftWheelDist;
|
||||
deltaDist = (rightWheelDist + leftWheelDist) / 2.0;
|
||||
|
@ -128,6 +158,69 @@ namespace create {
|
|||
vel.yaw = 0.0;
|
||||
}
|
||||
|
||||
// Update covariances
|
||||
// Ref: "Introduction to Autonomous Mobile Robots" (Siegwart 2004, page 189)
|
||||
float kr = 1.0; // TODO: Perform experiments to find these nondeterministic parameters
|
||||
float kl = 1.0;
|
||||
float cosYawAndHalfDelta = cos(pose.yaw + (deltaYaw / 2.0)); // deltaX?
|
||||
float sinYawAndHalfDelta = sin(pose.yaw + (deltaYaw / 2.0)); // deltaY?
|
||||
float distOverTwoWB = deltaDist / (util::CREATE_2_AXLE_LENGTH * 2.0);
|
||||
|
||||
Matrix invCovar(2, 2);
|
||||
invCovar(0, 0) = kr * fabs(rightWheelDist);
|
||||
invCovar(0, 1) = 0.0;
|
||||
invCovar(1, 0) = 0.0;
|
||||
invCovar(1, 1) = kl * fabs(leftWheelDist);
|
||||
|
||||
Matrix Finc(3, 2);
|
||||
Finc(0, 0) = (cosYawAndHalfDelta / 2.0) - (distOverTwoWB * sinYawAndHalfDelta);
|
||||
Finc(0, 1) = (cosYawAndHalfDelta / 2.0) + (distOverTwoWB * sinYawAndHalfDelta);
|
||||
Finc(1, 0) = (sinYawAndHalfDelta / 2.0) + (distOverTwoWB * cosYawAndHalfDelta);
|
||||
Finc(1, 1) = (sinYawAndHalfDelta / 2.0) - (distOverTwoWB * cosYawAndHalfDelta);
|
||||
Finc(2, 0) = (1.0 / util::CREATE_2_AXLE_LENGTH);
|
||||
Finc(2, 1) = (-1.0 / util::CREATE_2_AXLE_LENGTH);
|
||||
Matrix FincT = boost::numeric::ublas::trans(Finc);
|
||||
|
||||
Matrix Fp(3, 3);
|
||||
Fp(0, 0) = 1.0;
|
||||
Fp(0, 1) = 0.0;
|
||||
Fp(0, 2) = (-deltaDist) * sinYawAndHalfDelta;
|
||||
Fp(1, 0) = 0.0;
|
||||
Fp(1, 1) = 1.0;
|
||||
Fp(1, 2) = deltaDist * cosYawAndHalfDelta;
|
||||
Fp(2, 0) = 0.0;
|
||||
Fp(2, 1) = 0.0;
|
||||
Fp(2, 2) = 1.0;
|
||||
Matrix FpT = boost::numeric::ublas::trans(Fp);
|
||||
|
||||
Matrix velCovar = ublas::prod(invCovar, FincT);
|
||||
velCovar = ublas::prod(Finc, velCovar);
|
||||
|
||||
vel.covariance[0] = velCovar(0, 0);
|
||||
vel.covariance[1] = velCovar(0, 1);
|
||||
vel.covariance[2] = velCovar(0, 2);
|
||||
vel.covariance[3] = velCovar(1, 0);
|
||||
vel.covariance[4] = velCovar(1, 1);
|
||||
vel.covariance[5] = velCovar(1, 2);
|
||||
vel.covariance[6] = velCovar(2, 0);
|
||||
vel.covariance[7] = velCovar(2, 1);
|
||||
vel.covariance[8] = velCovar(2, 2);
|
||||
|
||||
Matrix poseCovarTmp = ublas::prod(poseCovar, FpT);
|
||||
poseCovarTmp = ublas::prod(Fp, poseCovarTmp);
|
||||
poseCovar = addMatrices(poseCovarTmp, velCovar);
|
||||
|
||||
pose.covariance[0] = poseCovar(0, 0);
|
||||
pose.covariance[1] = poseCovar(0, 1);
|
||||
pose.covariance[2] = poseCovar(0, 2);
|
||||
pose.covariance[3] = poseCovar(1, 0);
|
||||
pose.covariance[4] = poseCovar(1, 1);
|
||||
pose.covariance[5] = poseCovar(1, 2);
|
||||
pose.covariance[6] = poseCovar(2, 0);
|
||||
pose.covariance[7] = poseCovar(2, 1);
|
||||
pose.covariance[8] = poseCovar(2, 2);
|
||||
|
||||
// Update pose
|
||||
pose.x += deltaX;
|
||||
pose.y += deltaY;
|
||||
pose.yaw = util::normalizeAngle(pose.yaw + deltaYaw);
|
||||
|
@ -171,7 +264,24 @@ namespace create {
|
|||
//}
|
||||
|
||||
bool Create::setMode(const CreateMode& mode) {
|
||||
return serial->sendOpcode((Opcode) mode);
|
||||
switch (mode) {
|
||||
case MODE_OFF:
|
||||
return serial->sendOpcode(OC_POWER);
|
||||
break;
|
||||
case MODE_PASSIVE:
|
||||
return serial->sendOpcode(OC_START);
|
||||
break;
|
||||
case MODE_SAFE:
|
||||
return serial->sendOpcode(OC_SAFE);
|
||||
break;
|
||||
case MODE_FULL:
|
||||
return serial->sendOpcode(OC_FULL);
|
||||
break;
|
||||
default:
|
||||
CERR("[create::Create] ", "cannot set robot to mode '" << mode << "'");
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Create::clean(const CleanMode& mode) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue