Instantaneous velocity now available

This commit is contained in:
jacobperron 2016-02-02 19:31:06 -08:00
parent 43c7b95361
commit 81f18d58d4
4 changed files with 56 additions and 6 deletions

View file

@ -34,12 +34,12 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <string> #include <string>
#include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#include "create/serial.h" #include "create/serial.h"
#include "create/data.h" #include "create/data.h"
#include "create/types.h" #include "create/types.h"
#include "create/util.h"
namespace create { namespace create {
class Create { class Create {
@ -64,12 +64,14 @@ namespace create {
uint8_t powerLEDIntensity; uint8_t powerLEDIntensity;
create::Pose pose; create::Pose pose;
create::Vel vel;
uint32_t prevTicksLeft; uint32_t prevTicksLeft;
uint32_t prevTicksRight; uint32_t prevTicksRight;
float prevLeftVel; float prevLeftVel;
float prevRightVel; float prevRightVel;
bool firstOnData; bool firstOnData;
util::timestamp_t prevOnDataTime;
void init(); void init();
bool updateLEDs(); bool updateLEDs();
@ -346,6 +348,10 @@ namespace create {
/* Get the estimated position of Create based on it's wheel encoders. /* Get the estimated position of Create based on it's wheel encoders.
*/ */
const create::Pose& getPose() const; const create::Pose& getPose() const;
/* Get the estimated velocity of Create based on wheel encoders.
*/
const create::Vel& getVel() const;
}; // end Create class }; // end Create class
} // namespace create } // namespace create

View file

@ -185,6 +185,7 @@ namespace create {
float yaw; float yaw;
}; };
typedef Pose Vel;
} // namespace create } // namespace create
#endif // CREATE_TYPES_H #endif // CREATE_TYPES_H

View file

@ -32,6 +32,8 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef CREATE_UTIL_H #ifndef CREATE_UTIL_H
#define CREATE_UTIL_H #define CREATE_UTIL_H
#include <sys/time.h>
#define COUT(prefix,msg) (std::cout<<prefix<<msg<<std::endl) #define COUT(prefix,msg) (std::cout<<prefix<<msg<<std::endl)
#define CERR(prefix,msg) (std::cerr<<prefix<<msg<<std::endl) #define CERR(prefix,msg) (std::cerr<<prefix<<msg<<std::endl)
@ -46,7 +48,7 @@ namespace create {
static const float CREATE_2_MAX_VEL = 0.5; static const float CREATE_2_MAX_VEL = 0.5;
static const float PI = 3.14159; static const float PI = 3.14159;
static const float TWO_PI = 6.28318; static const float TWO_PI = 6.28318;
static const float EPS = 0.001; static const float EPS = 0.0001;
inline float normalizeAngle(const float& angle) { inline float normalizeAngle(const float& angle) {
float a = angle; float a = angle;
@ -55,6 +57,14 @@ namespace create {
return a; return a;
}; };
/** Get a timestamp for the current time in micro-seconds.
*/
typedef unsigned long long timestamp_t;
static timestamp_t getTimestamp() {
struct timeval now;
gettimeofday(&now, NULL);
return now.tv_usec + (timestamp_t) now.tv_sec * 1000000;
}
} // namespace util } // namespace util
} // namespace create } // namespace create

View file

@ -30,6 +30,9 @@ namespace create {
pose.x = 0; pose.x = 0;
pose.y = 0; pose.y = 0;
pose.yaw = 0; pose.yaw = 0;
vel.x = 0;
vel.y = 0;
vel.yaw = 0;
data = boost::shared_ptr<Data>(new Data()); data = boost::shared_ptr<Data>(new Data());
serial = boost::make_shared<Serial>(data); serial = boost::make_shared<Serial>(data);
} }
@ -52,9 +55,14 @@ namespace create {
// Initialize tick counts // Initialize tick counts
prevTicksLeft = GET_DATA(ID_LEFT_ENC); prevTicksLeft = GET_DATA(ID_LEFT_ENC);
prevTicksRight = GET_DATA(ID_RIGHT_ENC); prevTicksRight = GET_DATA(ID_RIGHT_ENC);
prevOnDataTime = util::getTimestamp();
firstOnData = false; firstOnData = false;
} }
// Get current time
util::timestamp_t curTime = util::getTimestamp();
float dt = (curTime - prevOnDataTime) / 1000000.0;
// Get cumulative ticks (wraps around at 65535) // Get cumulative ticks (wraps around at 65535)
uint16_t totalTicksLeft = GET_DATA(ID_LEFT_ENC); uint16_t totalTicksLeft = GET_DATA(ID_LEFT_ENC);
uint16_t totalTicksRight = GET_DATA(ID_RIGHT_ENC); uint16_t totalTicksRight = GET_DATA(ID_RIGHT_ENC);
@ -82,18 +90,39 @@ namespace create {
float deltaDist = (rightWheelDist + leftWheelDist) / 2.0; float deltaDist = (rightWheelDist + leftWheelDist) / 2.0;
// Moving straight // Moving straight
float deltaX, deltaY;
if (fabs(wheelDistDiff) < util::EPS) { if (fabs(wheelDistDiff) < util::EPS) {
pose.x += deltaDist * cos(pose.yaw); deltaX = deltaDist * cos(pose.yaw);
pose.y += deltaDist * sin(pose.yaw); deltaY = deltaDist * sin(pose.yaw);
vel.yaw = 0;
} }
else { else {
float turnRadius = (util::CREATE_2_AXLE_LENGTH / 2.0) * (leftWheelDist + rightWheelDist) / wheelDistDiff; float turnRadius = (util::CREATE_2_AXLE_LENGTH / 2.0) * (leftWheelDist + rightWheelDist) / wheelDistDiff;
float deltaYaw = (rightWheelDist - leftWheelDist) / util::CREATE_2_AXLE_LENGTH; float deltaYaw = (rightWheelDist - leftWheelDist) / util::CREATE_2_AXLE_LENGTH;
pose.x += turnRadius * (sin(pose.yaw + deltaYaw) - sin(pose.yaw)); deltaX = turnRadius * (sin(pose.yaw + deltaYaw) - sin(pose.yaw));
pose.y += turnRadius * (cos(pose.yaw + deltaYaw) - cos(pose.yaw)); deltaY = turnRadius * (cos(pose.yaw + deltaYaw) - cos(pose.yaw));
pose.yaw = util::normalizeAngle(pose.yaw + deltaYaw); pose.yaw = util::normalizeAngle(pose.yaw + deltaYaw);
if (fabs(dt) > util::EPS) {
vel.yaw = deltaYaw / dt;
}
else {
vel.yaw = 0;
}
} }
if (fabs(dt) > util::EPS) {
vel.x = deltaX / dt;
vel.y = deltaY / dt;
}
else {
vel.x = 0;
vel.y = 0;
}
pose.x += deltaDist * cos(pose.yaw);
pose.y += deltaDist * sin(pose.yaw);
prevOnDataTime = curTime;
// Make user registered callbacks, if any // Make user registered callbacks, if any
// TODO // TODO
} }
@ -472,4 +501,8 @@ namespace create {
return pose; return pose;
} }
const Vel& Create::getVel() const {
return vel;
}
} // end namespace } // end namespace