2007-02-18 00:14:00 +00:00
|
|
|
#include "navigator.h"
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Navigator::Stop()
|
|
|
|
{
|
2007-02-19 17:15:02 +00:00
|
|
|
this->direction = EMPTY_FLOAT;
|
|
|
|
this->targetAngle = EMPTY_FLOAT;
|
|
|
|
this->targetX = EMPTY_FLOAT;
|
|
|
|
this->targetY = EMPTY_FLOAT;
|
2007-02-18 17:57:03 +00:00
|
|
|
this->robotSpeed = 0;
|
2007-02-18 00:14:00 +00:00
|
|
|
this->rotationSpeed = 0;
|
|
|
|
|
|
|
|
for(uint8 i = IO_ENGINE_START; i < IO_ENGINE_END; i++)
|
|
|
|
{
|
|
|
|
(parent->GetModule<Engine>(i))->SetSpeed(0);
|
|
|
|
(parent->GetModule<Engine>(i))->SetEnabled(true);
|
|
|
|
}
|
2007-02-19 20:57:03 +00:00
|
|
|
}
|
|
|
|
|
2007-02-19 22:02:01 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Navigator::Rotate(float rotationSpeed)
|
2007-02-19 20:57:03 +00:00
|
|
|
{
|
2007-02-19 22:02:01 +00:00
|
|
|
this->rotationSpeed = min(fabs(rotationSpeed), 255.0f) * sign(rotationSpeed);
|
2007-02-19 17:15:02 +00:00
|
|
|
this->direction = EMPTY_FLOAT;
|
|
|
|
this->targetAngle = EMPTY_FLOAT;
|
|
|
|
this->targetX = EMPTY_FLOAT;
|
|
|
|
this->targetY = EMPTY_FLOAT;
|
2007-02-18 17:57:03 +00:00
|
|
|
this->robotSpeed = 0;
|
2007-02-18 00:14:00 +00:00
|
|
|
|
|
|
|
for(uint8 i = IO_ENGINE_START; i < IO_ENGINE_END; i++)
|
|
|
|
{
|
|
|
|
(parent->GetModule<Engine>(i))->SetSpeed(rotationSpeed);
|
|
|
|
(parent->GetModule<Engine>(i))->SetEnabled(true);
|
|
|
|
}
|
2007-02-19 22:02:01 +00:00
|
|
|
}
|
|
|
|
|
2007-02-18 17:57:03 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Navigator::Drive(float newDirection, float newAngle, float newSpeed, float rotationSpeed)
|
|
|
|
{
|
|
|
|
this->rotationSpeed = min(rotationSpeed, 255.0f);
|
2007-02-19 22:02:01 +00:00
|
|
|
this->direction = newDirection * PI / 180.0f;
|
|
|
|
this->targetAngle = newAngle * PI / 180.0f;
|
2007-02-19 17:15:02 +00:00
|
|
|
this->targetX = EMPTY_FLOAT;
|
|
|
|
this->targetY = EMPTY_FLOAT;
|
2007-02-18 17:57:03 +00:00
|
|
|
this->robotSpeed = newSpeed;
|
|
|
|
|
2007-02-19 17:15:02 +00:00
|
|
|
if(targetAngle == EMPTY_FLOAT)
|
2007-02-18 17:57:03 +00:00
|
|
|
{
|
2007-02-19 17:15:02 +00:00
|
|
|
rotationSpeed = 0;
|
2007-02-18 17:57:03 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-02-19 17:15:02 +00:00
|
|
|
rotationSpeed = fabs(rotationSpeed) * sign(PI - (targetAngle - (parent->GetModule<Position_Tracker>(IO_POSITION_TRACKER_MAIN))->GetOrientation()));
|
2007-02-18 17:57:03 +00:00
|
|
|
}
|
|
|
|
|
2007-02-19 17:15:02 +00:00
|
|
|
CalculateEngines();
|
2007-02-19 22:02:01 +00:00
|
|
|
}
|
|
|
|
|
2007-02-18 17:57:03 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Navigator::DriveTo(float newX, float newY, float newAngle, float newSpeed, float rotationSpeed)
|
|
|
|
{
|
2007-02-26 21:25:01 +00:00
|
|
|
if(newX == EMPTY_FLOAT || newY == EMPTY_FLOAT) return;
|
2007-02-18 17:57:03 +00:00
|
|
|
|
|
|
|
Position_Tracker* locationeer = parent->GetModule<Position_Tracker>(IO_POSITION_TRACKER_MAIN);
|
|
|
|
|
|
|
|
this->rotationSpeed = min(rotationSpeed, 255.0f);
|
|
|
|
this->targetX = newX;
|
|
|
|
this->targetY = newY;
|
2007-02-22 23:04:02 +00:00
|
|
|
this->direction = direction2d(locationeer->GetPositionX(), locationeer->GetPositionY(), targetX, targetY);
|
2007-02-19 22:02:01 +00:00
|
|
|
this->targetAngle = newAngle * PI / 180.0f;
|
2007-02-18 17:57:03 +00:00
|
|
|
this->robotSpeed = newSpeed;
|
|
|
|
|
|
|
|
if(targetAngle - locationeer->GetOrientation() > PI)
|
|
|
|
{
|
|
|
|
if(rotationSpeed > 0)
|
|
|
|
{
|
|
|
|
rotationSpeed = -rotationSpeed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(rotationSpeed < 0)
|
|
|
|
{
|
|
|
|
rotationSpeed = -rotationSpeed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-22 20:59:02 +00:00
|
|
|
CalculateDirection();
|
|
|
|
}
|
|
|
|
|
2007-02-22 23:04:02 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Navigator::RotateTo(float newAngle, float rotationSpeed)
|
|
|
|
{
|
2007-02-22 20:59:02 +00:00
|
|
|
Position_Tracker* locationeer = parent->GetModule<Position_Tracker>(IO_POSITION_TRACKER_MAIN);
|
|
|
|
|
2007-02-22 23:04:02 +00:00
|
|
|
this->targetX = EMPTY_FLOAT;
|
|
|
|
this->targetY = EMPTY_FLOAT;
|
|
|
|
this->direction = EMPTY_FLOAT;
|
2007-02-22 20:59:02 +00:00
|
|
|
this->rotationSpeed = min(rotationSpeed, 255.0f);
|
|
|
|
this->targetAngle = newAngle * PI / 180.0f;
|
2007-02-22 23:04:02 +00:00
|
|
|
this->robotSpeed = 0;
|
2007-02-22 20:59:02 +00:00
|
|
|
|
|
|
|
if(targetAngle - locationeer->GetOrientation() > PI)
|
|
|
|
{
|
|
|
|
if(rotationSpeed > 0)
|
|
|
|
{
|
|
|
|
rotationSpeed = -rotationSpeed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(rotationSpeed < 0)
|
|
|
|
{
|
|
|
|
rotationSpeed = -rotationSpeed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-19 17:15:02 +00:00
|
|
|
CalculateDirection();
|
2007-02-19 22:02:01 +00:00
|
|
|
}
|
2007-02-22 20:59:02 +00:00
|
|
|
|
2007-02-22 23:04:02 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool Navigator::TargetReached()
|
|
|
|
{
|
2007-02-18 00:14:00 +00:00
|
|
|
Position_Tracker* locationeer = parent->GetModule<Position_Tracker>(IO_POSITION_TRACKER_MAIN);
|
|
|
|
|
2007-02-19 17:15:02 +00:00
|
|
|
bool targetReached = false;
|
2007-02-18 00:14:00 +00:00
|
|
|
|
2007-02-26 21:25:01 +00:00
|
|
|
if(!HasTarget() || (distance2d(targetX, targetY, locationeer->GetPositionX(), locationeer->GetPositionY()) < DISTANCE_TOLERANCE))
|
2007-02-18 00:14:00 +00:00
|
|
|
{
|
2007-02-19 17:15:02 +00:00
|
|
|
targetReached = true;
|
2007-02-18 00:14:00 +00:00
|
|
|
}
|
2007-02-19 17:15:02 +00:00
|
|
|
|
2007-02-22 20:59:02 +00:00
|
|
|
return targetReached;
|
|
|
|
}
|
|
|
|
|
2007-02-22 23:04:02 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool Navigator::AngleReached()
|
|
|
|
{
|
2007-02-22 20:59:02 +00:00
|
|
|
Position_Tracker* locationeer = parent->GetModule<Position_Tracker>(IO_POSITION_TRACKER_MAIN);
|
|
|
|
|
|
|
|
bool targetAngleReached = false;
|
|
|
|
|
2007-02-22 23:04:02 +00:00
|
|
|
if(!HasTargetAngle() || (fabs(targetAngle - locationeer->GetOrientation()) < 0.1f))
|
2007-02-18 00:14:00 +00:00
|
|
|
{
|
2007-02-19 17:15:02 +00:00
|
|
|
targetAngleReached = true;
|
2007-02-18 00:14:00 +00:00
|
|
|
}
|
2007-02-22 23:04:02 +00:00
|
|
|
|
2007-02-22 20:59:02 +00:00
|
|
|
return targetAngleReached;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Navigator::Update()
|
|
|
|
{
|
2007-02-22 23:04:02 +00:00
|
|
|
if(this->direction == EMPTY_FLOAT || (HasTarget() && TargetReached()))
|
2007-02-18 00:14:00 +00:00
|
|
|
{
|
2007-02-22 23:04:02 +00:00
|
|
|
if(this->rotationSpeed == 0 || (HasTargetAngle() && AngleReached()))
|
|
|
|
{
|
|
|
|
Stop();
|
|
|
|
}
|
|
|
|
else if(!AngleReached())
|
|
|
|
{
|
|
|
|
RotateTo(this->targetAngle, this->rotationSpeed);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Rotate(this->rotationSpeed);
|
|
|
|
}
|
2007-02-19 17:15:02 +00:00
|
|
|
}
|
2007-02-22 23:04:02 +00:00
|
|
|
else
|
2007-02-19 17:15:02 +00:00
|
|
|
{
|
2007-02-22 23:04:02 +00:00
|
|
|
if(this->rotationSpeed == 0 || (HasTargetAngle() && AngleReached()))
|
|
|
|
{
|
|
|
|
this->rotationSpeed = 0;
|
|
|
|
this->targetAngle = EMPTY_FLOAT;
|
|
|
|
|
|
|
|
CalculateDirection();
|
|
|
|
}
|
|
|
|
}
|
2007-02-18 00:14:00 +00:00
|
|
|
|
2007-02-19 17:15:02 +00:00
|
|
|
if(!(correctionCountdown--))
|
2007-02-18 00:14:00 +00:00
|
|
|
{
|
2007-02-19 17:15:02 +00:00
|
|
|
CalculateDirection();
|
2007-02-18 00:14:00 +00:00
|
|
|
}
|
2007-02-19 22:02:01 +00:00
|
|
|
}
|
|
|
|
|
2007-02-19 17:15:02 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Navigator::CalculateDirection()
|
|
|
|
{
|
|
|
|
correctionCountdown = CYCLES_PER_CORRECTION;
|
|
|
|
|
|
|
|
if(targetAngle == EMPTY_FLOAT && !HasTarget()) return;
|
|
|
|
|
|
|
|
Position_Tracker* locationeer = parent->GetModule<Position_Tracker>(IO_POSITION_TRACKER_MAIN);
|
|
|
|
|
|
|
|
if(HasTarget())
|
2007-02-18 00:14:00 +00:00
|
|
|
{
|
2007-02-19 17:15:02 +00:00
|
|
|
direction = direction2d(locationeer->GetPositionX(), locationeer->GetPositionY(), targetX, targetY);
|
2007-02-18 00:14:00 +00:00
|
|
|
}
|
|
|
|
|
2007-02-19 17:15:02 +00:00
|
|
|
if(targetAngle != EMPTY_FLOAT)
|
2007-02-18 00:14:00 +00:00
|
|
|
{
|
2007-02-19 17:15:02 +00:00
|
|
|
rotationSpeed = fabs(rotationSpeed) * sign(PI - (targetAngle - locationeer->GetOrientation()));
|
|
|
|
}
|
2007-02-18 00:14:00 +00:00
|
|
|
|
2007-02-19 17:15:02 +00:00
|
|
|
CalculateEngines();
|
2007-02-19 22:02:01 +00:00
|
|
|
}
|
|
|
|
|
2007-02-19 17:15:02 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Navigator::CalculateEngines()
|
|
|
|
{
|
2007-02-22 13:12:03 +00:00
|
|
|
// Use the position_tracker
|
2007-02-20 21:01:02 +00:00
|
|
|
Position_Tracker* locationeer = parent->GetModule<Position_Tracker>(IO_POSITION_TRACKER_MAIN);
|
2007-02-22 13:12:03 +00:00
|
|
|
// get the relative position of the robot
|
|
|
|
float relativeDirection = this->direction - locationeer->GetOrientation();
|
2007-02-18 00:14:00 +00:00
|
|
|
|
2007-02-22 13:12:03 +00:00
|
|
|
// calculate x and y-koordinates
|
|
|
|
float xDrive = cos(relativeDirection + PI / 6.0f);
|
|
|
|
float yDrive = sin(relativeDirection + PI / 6.0f);
|
2007-02-18 00:14:00 +00:00
|
|
|
|
2007-02-22 13:12:03 +00:00
|
|
|
// calculate relative speed of engines
|
|
|
|
float vLeft = xDrive;
|
|
|
|
float vBack = (-xDrive + sqrt(3) * yDrive) / 2.0f;
|
|
|
|
float vRight = (-xDrive - sqrt(3) * yDrive) / 2.0f;
|
2007-02-18 17:57:03 +00:00
|
|
|
|
2007-02-22 13:12:03 +00:00
|
|
|
// Get the maximal value
|
|
|
|
float speedCorrection = (float)max(max(fabs(vLeft),fabs(vBack)),fabs(vRight));
|
2007-02-18 00:14:00 +00:00
|
|
|
|
2007-02-22 13:12:03 +00:00
|
|
|
// calculate the correct speeds of the engines
|
|
|
|
vLeft = ((float)vLeft * (float)((float)this->robotSpeed / (float)speedCorrection)) + this->rotationSpeed;
|
|
|
|
vBack = ((float)vBack * (float)((float)this->robotSpeed / (float)speedCorrection)) + this->rotationSpeed;
|
|
|
|
vRight = ((float)vRight * (float)((float)this->robotSpeed / (float)speedCorrection)) + this->rotationSpeed;
|
2007-02-18 00:14:00 +00:00
|
|
|
|
2007-02-26 21:25:01 +00:00
|
|
|
(parent->GetModule<Display>(IO_DISPLAY_MAIN))->Print(vBack,10,2);
|
2007-02-22 13:12:03 +00:00
|
|
|
//(parent->GetModule<Display>(IO_DISPLAY_MAIN))->Print(vBack,10,3);
|
|
|
|
//(parent->GetModule<Display>(IO_DISPLAY_MAIN))->Print(vRight,10,4);
|
2007-02-18 00:14:00 +00:00
|
|
|
|
2007-02-22 13:12:03 +00:00
|
|
|
// Transfer the values to the engines
|
|
|
|
Engine* curEngine = parent->GetModule<Engine>(IO_ENGINE_DRIVE_LEFT);
|
|
|
|
curEngine->SetSpeed(vLeft);
|
|
|
|
curEngine->SetEnabled(true);
|
|
|
|
curEngine = parent->GetModule<Engine>(IO_ENGINE_DRIVE_BACK);
|
|
|
|
curEngine->SetSpeed(vBack);
|
|
|
|
curEngine->SetEnabled(true);
|
|
|
|
curEngine = parent->GetModule<Engine>(IO_ENGINE_DRIVE_RIGHT);
|
|
|
|
curEngine->SetSpeed(vRight);
|
|
|
|
curEngine->SetEnabled(true);
|
|
|
|
curEngine = NULL;
|
2007-02-19 22:02:01 +00:00
|
|
|
}
|