#include "navigator.h" //----------------------------------------------------------------------------- void Navigator::Stop() { this->direction = -1.0f; this->targetAngle = -1.0f; this->targetX = -1.0f; this->targetY = -1.0f; this->robotSpeed = 0; this->rotationSpeed = 0; for(uint8 i = IO_ENGINE_START; i < IO_ENGINE_END; i++) { (parent->GetModule(i))->SetSpeed(0); (parent->GetModule(i))->SetEnabled(true); } } //----------------------------------------------------------------------------- void Navigator::Rotate(float rotationSpeed) { this->rotationSpeed = min(rotationSpeed, 255.0f);; this->direction = -1.0f; this->targetAngle = -1.0f; this->targetX = -1.0f; this->targetY = -1.0f; this->robotSpeed = 0; for(uint8 i = IO_ENGINE_START; i < IO_ENGINE_END; i++) { (parent->GetModule(i))->SetSpeed(rotationSpeed); (parent->GetModule(i))->SetEnabled(true); } } //----------------------------------------------------------------------------- void Navigator::Drive(float newDirection, float newAngle, float newSpeed, float rotationSpeed) { this->rotationSpeed = min(rotationSpeed, 255.0f); this->direction = newDirection; this->targetAngle = newAngle; this->targetX = -1.0f; this->targetY = -1.0f; this->robotSpeed = newSpeed; if(targetAngle - (parent->GetModule(IO_POSITION_TRACKER_MAIN))->GetOrientation() > PI) { if(rotationSpeed > 0) { rotationSpeed = -rotationSpeed; } } else { if(rotationSpeed < 0) { rotationSpeed = -rotationSpeed; } } Update(); } //----------------------------------------------------------------------------- void Navigator::DriveTo(float newX, float newY, float newAngle, float newSpeed, float rotationSpeed) { if(newX < 0 || newY < 0) return; Position_Tracker* locationeer = parent->GetModule(IO_POSITION_TRACKER_MAIN); this->rotationSpeed = min(rotationSpeed, 255.0f); this->targetX = newX; this->targetY = newY; this->direction = direction2d(locationeer->GetPositionX(), locationeer->GetPositionY(), targetX, targetY);; this->targetAngle = newAngle; this->robotSpeed = newSpeed; if(targetAngle - locationeer->GetOrientation() > PI) { if(rotationSpeed > 0) { rotationSpeed = -rotationSpeed; } } else { if(rotationSpeed < 0) { rotationSpeed = -rotationSpeed; } } Update(); } //----------------------------------------------------------------------------- void Navigator::Update() { Position_Tracker* locationeer = parent->GetModule(IO_POSITION_TRACKER_MAIN); bool hasDistanceToDrive = true; bool hasOrientationToAdjust = true; //Check for distance to drive if((targetX >= 0) != (targetY >= 0)) { targetX = -1.0f; targetY = -1.0f; hasDistanceToDrive = false; } else if(targetX >= 0 && targetY >= 0) { if(distance2d(targetX, targetY, locationeer->GetPositionX(), locationeer->GetPositionY()) < 1.0f) { targetX = -1.0f; targetY = -1.0f; hasDistanceToDrive = false; } else { hasDistanceToDrive = true; } } else { if(direction >= 0) { hasDistanceToDrive = true; } else { hasDistanceToDrive = false; } } //Check for orientation to adjust if(targetAngle >= 0) { if(fabs(targetAngle - locationeer->GetOrientation()) < 0.1f) { hasOrientationToAdjust = false; } else { hasOrientationToAdjust = true; } } else { if(rotationSpeed != 0) { hasOrientationToAdjust = true; } else { hasOrientationToAdjust = false; } } //Calculate directional/rotational engine speed if(hasDistanceToDrive) { float relativeDirection = this->direction - locationeer->GetOrientation(); if(targetX >= 0 && targetY >= 0) { float directionToTarget = direction2d(locationeer->GetPositionX(), locationeer->GetPositionY(), targetX, targetY); relativeDirection = directionToTarget - locationeer->GetOrientation(); } float xDrive = cos(relativeDirection); float yDrive = sin(relativeDirection); float vLeft = (-yDrive + sqrt(3) * xDrive) / 2.0f; float vBack = yDrive; float vRight = (-yDrive - sqrt(3) * xDrive)/2; float speedCorrection = 1.0f; float maxEngineSpeed = 255.0f; float minEngineSpeed = -255.0f; float maxSingleSpeed = max(max(vLeft, vBack), vRight); float calcSpeed = sqrt(vLeft * vLeft - vLeft * vRight + vRight * vRight + vBack * (vBack + vLeft + vRight)); if(calcSpeed != 1.0f) { speedCorrection = 1.0f / calcSpeed; } float maxOverallSpeed = robotSpeed * maxSingleSpeed * speedCorrection; if(maxOverallSpeed > maxEngineSpeed) { robotSpeed = maxEngineSpeed / (maxSingleSpeed * speedCorrection); } vLeft = vLeft * this->robotSpeed * speedCorrection; vBack = vBack * this->robotSpeed * speedCorrection; vRight = vRight * this->robotSpeed * speedCorrection; maxSingleSpeed = max(max(vLeft, vBack), vRight); float minSingleSpeed = min(min(vLeft, vBack), vRight); if(hasOrientationToAdjust) { if(this->rotationSpeed > 0) { if(maxEngineSpeed - maxSingleSpeed < this->rotationSpeed) { vLeft += maxEngineSpeed - maxSingleSpeed; vBack += maxEngineSpeed - maxSingleSpeed; vRight += maxEngineSpeed - maxSingleSpeed; } else { vLeft += this->rotationSpeed; vBack += this->rotationSpeed; vRight += this->rotationSpeed; } } else { if((minEngineSpeed - minSingleSpeed) < this->rotationSpeed) { vLeft -= minEngineSpeed - minSingleSpeed; vBack -= minEngineSpeed - minSingleSpeed; vRight -= minEngineSpeed - minSingleSpeed; } else { vLeft -= this->rotationSpeed; vBack -= this->rotationSpeed; vRight -= this->rotationSpeed; } } } Engine* curEngine = parent->GetModule(IO_ENGINE_DRIVE_LEFT); curEngine->SetSpeed(vLeft); curEngine->SetEnabled(true); curEngine = parent->GetModule(IO_ENGINE_DRIVE_BACK); curEngine->SetSpeed(vBack); curEngine->SetEnabled(true); curEngine = parent->GetModule(IO_ENGINE_DRIVE_RIGHT); curEngine->SetSpeed(vRight); curEngine->SetEnabled(true); curEngine = NULL; } else if(hasOrientationToAdjust) { Engine* curEngine = parent->GetModule(IO_ENGINE_DRIVE_LEFT); curEngine->SetSpeed(this->rotationSpeed); curEngine->SetEnabled(true); curEngine = parent->GetModule(IO_ENGINE_DRIVE_BACK); curEngine->SetSpeed(this->rotationSpeed); curEngine->SetEnabled(true); curEngine = parent->GetModule(IO_ENGINE_DRIVE_RIGHT); curEngine->SetSpeed(this->rotationSpeed); curEngine->SetEnabled(true); curEngine = NULL; } else { Stop(); } }