#include "Aria.h"
class Chase : public ArAction
{
public:
enum State {
NO_TARGET,
TARGET,
};
Chase(ArACTS_1_2 *acts, ArVCC4 *camera);
~Chase(void);
ArActionDesired *fire(ArActionDesired currentDesired);
bool setChannel(int channel);
State getState(void) { return myState; }
enum {
WIDTH = 160,
HEIGHT = 120
};
protected:
ArActionDesired myDesired;
ArACTS_1_2 *myActs;
ArVCC4 *myCamera;
ArTime myLastSeen;
State myState;
int myChannel;
int myMaxTime;
};
Chase::Chase(ArACTS_1_2 *acts, ArVCC4 *camera) :
ArAction("Chase", "Chases the largest blob.")
{
myActs = acts;
myCamera = camera;
myChannel = 0;
myState = NO_TARGET;
setChannel(1);
myLastSeen.setToNow();
myMaxTime = 1000;
}
Chase::~Chase(void) {}
ArActionDesired *Chase::fire(ArActionDesired currentDesired)
{
ArACTSBlob blob;
ArACTSBlob largestBlob;
bool flag = false;
int numberOfBlobs;
int blobArea = 10;
double xRel, yRel;
myDesired.reset();
numberOfBlobs = myActs->getNumBlobs(myChannel);
if(numberOfBlobs != 0)
{
for(int i = 0; i < numberOfBlobs; i++)
{
myActs->getBlob(myChannel, i + 1, &blob);
if(blob.getArea() > blobArea)
{
flag = true;
blobArea = blob.getArea();
largestBlob = blob;
}
}
myLastSeen.setToNow();
}
if (myLastSeen.mSecSince() > myMaxTime)
{
if(myState != NO_TARGET) ArLog::log(ArLog::Normal, "Target Lost");
myState = NO_TARGET;
}
else
{
if(myState != TARGET) ArLog::log(ArLog::Normal, "Target Aquired");
myState = TARGET;
}
if(TARGET && flag == true)
{
xRel = (double)(largestBlob.getXCG() - WIDTH/2.0) / (double)WIDTH;
yRel = (double)(largestBlob.getYCG() - HEIGHT/2.0) / (double)HEIGHT;
if(!(ArMath::fabs(yRel) < .20))
{
if (-yRel > 0)
myCamera->tiltRel(1);
else
myCamera->tiltRel(-1);
}
if (ArMath::fabs(xRel) < .10)
{
myDesired.setDeltaHeading(0);
}
else
{
if (ArMath::fabs(-xRel * 10) <= 10)
myDesired.setDeltaHeading(-xRel * 10);
else if (-xRel > 0)
myDesired.setDeltaHeading(10);
else
myDesired.setDeltaHeading(-10);
}
myDesired.setVel(200);
return &myDesired;
}
else
{
myDesired.setVel(0);
myDesired.setDeltaHeading(0);
return &myDesired;
}
}
bool Chase::setChannel(int channel)
{
if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS)
{
myChannel = channel;
return true;
}
else
return false;
}
int main(int argc, char** argv)
{
Aria::init();
ArRobot robot;
ArKeyHandler keyHandler;
ArSonarDevice sonar;
ArVCC4 vcc4 (&robot);
ArACTS_1_2 acts;
ArArgumentParser argParser(&argc, argv);
argParser.loadDefaultArguments();
ArSimpleConnector simpleConnector(&argParser);
if (!Aria::parseArgs())
{
Aria::logOptions();
keyHandler.restore();
Aria::shutdown();
return 1;
}
ArActionLimiterForwards limiter("speed limiter near", 300, 600, 250);
ArActionLimiterForwards limiterFar("speed limiter far", 300, 1100, 400);
ArActionLimiterBackwards backwardsLimiter;
ArActionConstantVelocity stop("stop", 0);
ArActionConstantVelocity backup("backup", -200);
Chase chase(&acts, &vcc4);
Aria::setKeyHandler(&keyHandler);
robot.attachKeyHandler(&keyHandler);
robot.addRangeDevice(&sonar);
if (!simpleConnector.connectRobot(&robot))
{
printf("Could not connect to robot... exiting\n");
keyHandler.restore();
Aria::shutdown();
return 1;
}
acts.openPort(&robot);
vcc4.init();
ArUtil::sleep(1000);
robot.setAbsoluteMaxTransVel(400);
robot.comInt(ArCommands::ENABLE, 1);
robot.comInt(ArCommands::SOUNDTOG, 0);
ArUtil::sleep(200);
robot.addAction(&limiter, 100);
robot.addAction(&limiterFar, 99);
robot.addAction(&backwardsLimiter, 98);
robot.addAction(&chase, 77);
robot.addAction(&backup, 50);
robot.addAction(&stop, 30);
robot.run(true);
Aria::shutdown();
return 0;
}