// ai.cc // nono - programme du robot 2004. {{{ // // Copyright (C) 2004 Nicolas Schodet // // Robot APB Team/Efrei 2004. // Web: http://assos.efrei.fr/robot/ // Email: robot AT efrei DOT fr // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // }}} #include "ai.h" #include "motor/movement_types.h" #include "motor/movement_reposition.h" #include "date/date.h" #include #include /// Constructeur. Ai::Ai (void) : ana_ (gspp_), ga_ (motor_.getAsserv ()), gc_ (ga_, gspp_, ga_.getNbIo ()), gp_ (gc_), v4l_ ("/dev/video", ImageLoader::yuv), lastCapture_ (0), front_ (135), bigFront_ (182), width_ (260), rear_ (135), roulOn_ (false), roulRev_ (false) { gpioJack_ = gp_.getByName ("jack"); gpioRoul_ = gp_.getByName ("roul"); gpioRoulS_ = gp_.getByName ("rouls"); gpioContactL_ = gp_.getByName ("contactl"); gpioContactR_ = gp_.getByName ("contactr"); anaSharpL_ = ana_.getByName ("ana1"); anaSharpR_ = ana_.getByName ("ana0"); } /// Initialise le robot. void Ai::init (void) { wait (500); benneUp (false); rouleau (false, false); motor_.go (); //v4l_.calibrate (); } /// Arrète le robot. void Ai::stop (void) { /// Attend l'arret complet de l'appareil. motor_.waitStopped (); } /// Lance le robot. void Ai::run (void) { try { waitJack (false); rouleau (true, false); wait (500); rouleau (false, false); waitJack (true); Date::getInstance ().startRound (); rouleau (true, false); goTo (900, 1500); goTo (900, 1800); goTo (2400, 1800); benneUp (true); recaleX (9 * 300 - front_, 0); decharge (1000); basic (-0.5, 150); benneUp (false); rotation (-M_PI / 2); goTo (2400, 300); rotation (0); benneUp (true); recaleX (9 * 300 - front_, 0); decharge (1000); basic (-0.5, 150); benneUp (false); rotation (M_PI); goTo (600, 300); benneUp (true); recaleX (1 * 300 + front_, M_PI); basic (-0.5, 150); benneUp (false); rotation (0); basic (0.5, 1800); benneUp (true); recaleX (9 * 300 - front_, 0); decharge (3000); basic (-0.5, 150); benneUp (false); } catch (FinDeMatch &e) { } } /// Mises à jour périodiques. void Ai::update (void) { // Mise à jour moteur. motor_.waitOk (); // Mise à jour capteurs. gspp_.update (); // Mise à jour camera. if (lastCapture_ + captureInterval_ < Date::getInstance ().start ()) { } } /// Mises à jour jusqu'à fin du mouvement en cours. void Ai::updateToEnd (void) { while (!motor_.end ()) { if (Date::getInstance ().round () >= roundDuration_) throw FinDeMatch (); update (); } } /// Mises à jour jusqu'à timeout. void Ai::updateWait (int t) { int start; start = Date::getInstance ().start (); while (Date::getInstance ().start () < start + t) { if (Date::getInstance ().round () >= roundDuration_) throw FinDeMatch (); update (); } } /// Lève (true) ou baisse (false) la benne. void Ai::benneUp (bool f) { gspp_.moveTo (1, f ? 5 : 57); } /// Fait tourner le rouleau. void Ai::rouleau (bool on, bool rev) { if (rev != roulRev_) { if (roulOn_) { gp_.set (gpioRoul_, 0); roulOn_ = false; updateWait (200); } gp_.set (gpioRoulS_, rev ? 1 : 0); roulRev_ = rev; if (on) updateWait (200); } if (on != roulOn_) { gp_.set (gpioRoul_, on ? 1 : 0); roulOn_ = on; } } /// Attend. void Ai::wait (int t) { updateWait (t); } /// Attend le jack entré (false) ou sorti (true). void Ai::waitJack (bool out) { while (gp_.get (gpioJack_) != (out ? 1u : 0u)) updateWait (50); } /// Rejoint un point. void Ai::goTo (double x, double y) { Goto *g = new GotoSimple (x, y); Movement *m = new MovementGoto (g); motor_.addMovement (m); updateToEnd (); } /// Recale contre une bordure. void Ai::recale (void) { Movement *m = new MovementReposition (0.2, gp_, gpioContactL_, gpioContactR_, ana_, anaSharpL_, anaSharpR_); motor_.addMovement (m); updateToEnd (); } /// Recale et ajuste en X contre une bordure. void Ai::recaleX (double x, double a) { recale (); } /// Mouvement basic. void Ai::basic (double v, double d) { Movement *m = new MovementBasic (v, d); motor_.addMovement (m); updateToEnd (); } /// Rotation. void Ai::rotation (double a) { Movement *m = new MovementRotation (a); motor_.addMovement (m); updateToEnd (); } /// Décharge la benne. void Ai::decharge (int t) { rouleau (true, true); wait (t); rouleau (true, false); } int main (int argc, char **argv) { Ai qdai_; qdai_.init (); qdai_.run (); qdai_.stop (); }