summaryrefslogtreecommitdiffstats
path: root/source/ct-Bot/rc5.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/ct-Bot/rc5.c')
-rw-r--r--source/ct-Bot/rc5.c502
1 files changed, 502 insertions, 0 deletions
diff --git a/source/ct-Bot/rc5.c b/source/ct-Bot/rc5.c
new file mode 100644
index 0000000..72cb20d
--- /dev/null
+++ b/source/ct-Bot/rc5.c
@@ -0,0 +1,502 @@
+/*
+ * c't-Sim - Robotersimulator fuer den c't-Bot
+ *
+ * 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.
+ *
+ */
+
+/*! @file rc5.c
+ * @brief RC5-Fernbedienung
+ * Um RC5-Codes fuer eine eigene Fernbedienung anzupassen, reicht es diese
+ * in eine Header-Datei auszulagern und anstatt der rc5code.h einzubinden.
+ * Die Maskierung fuer die Auswertung der Codes nicht vergessen!
+ * @author Benjamin Benz (bbe@heise.de)
+ * @date 20.12.05
+*/
+#include "bot-logic/bot-logik.h"
+#include "map.h"
+#include "ir-rc5.h"
+#include "display.h"
+#include "motor-low.h"
+
+#include "rc5-codes.h"
+
+
+
+#include <stdlib.h>
+
+#ifdef RC5_AVAILABLE
+
+/*!
+ * Dieser Typ definiert Parameter fuer RC5-Kommando-Code Funktionen.
+ */
+typedef struct {
+ uint16 value1; /*!< Wert 1 */
+ uint16 value2; /*!< Wert 2 */
+} RemCtrlFuncPar;
+
+/*! Dieser Typ definiert die RC5-Kommando-Code Funktion. */
+typedef void (*RemCtrlFunc)(RemCtrlFuncPar *par);
+
+/*! Dieser Typ definiert den RC5-Kommando-Code und die auszufuehrende Funktion. */
+typedef struct {
+ uint16 command; /*!< Kommando Code */
+ RemCtrlFunc func; /*!< Auszufuehrende Funktion */
+ RemCtrlFuncPar par; /*!< Parameter */
+} RemCtrlAction;
+
+/*!
+ * Diese Funktion setzt das Display auf eine andere Ausgabe.
+ * @param par Parameter mit dem zu setzenden Screen.
+ */
+#ifdef DISPLAY_SCREENS_AVAILABLE
+ static void rc5_screen_set(RemCtrlFuncPar *par);
+#endif
+
+#ifdef JOGDIAL
+/*!
+ * Diese Funktion setzt die Geschwindigkeit auf den angegebenen Wert.
+ * @param par Parameter mit den zu setzenden Geschwindigkeiten.
+ */
+static void rc5_bot_set_speed(RemCtrlFuncPar *par);
+#endif
+
+/*!
+ * Diese Funktion aendert die Geschwindigkeit um den angegebenen Wert.
+ * @param par Parameter mit den relativen Geschwindigkeitsaenderungen.
+ */
+#ifdef BEHAVIOUR_AVAILABLE
+ static void rc5_bot_change_speed(RemCtrlFuncPar *par);
+#endif
+
+/*!
+ * Diese Funktion wechselt zwischen verschiednen Verhalten
+ * @param par Parameter mit den zu setzenden Geschwindigkeiten.
+ */
+void rc5_bot_next_behaviour(RemCtrlFuncPar *par);
+
+
+/*!
+ * Diese Funktion stellt die Not-Aus-Funktion dar. Sie laesst den Bot anhalten
+ * und setzt alle Verhalten zurueck.
+ * @param par notwendiger Dummy-Parameter.
+ */
+static void rc5_emergency_stop(RemCtrlFuncPar *par);
+
+/*!
+* Verarbeitet die Zifferntasten in Abhaengigkeit vom eingestelltem Screen
+* @param par Parameter mit der betaetigten Zahlentaste.
+*/
+void rc5_number(RemCtrlFuncPar *par);
+
+#ifdef DISPLAY_BEHAVIOUR_AVAILABLE
+ /*!
+ * Diese Funktion setzt die Aktivitaeten der Verhalten nach der Auswahl.
+ * Hierdurch erfolgt der Startschuss fuer Umschaltung der Verhalten
+ */
+ #ifndef DISPLAY_DYNAMIC_BEHAVIOUR_AVAILABLE
+ static void rc5_set_all_behaviours(void) ;
+ #endif
+ /*!
+ * toggled ein Verhalten der Verhaltensliste an Position pos,
+ * die Aenderung erfolgt nur auf die Puffervariable
+ * @param i Verhaltens-Listenposition, entspricht der Taste 1-6 der gewaehlten Verhaltensseite
+ */
+ static void rc5_toggle_behaviour_new(int8 i);
+#endif
+
+/*! Steuert den Servo an
+ * @param par Parameter mit Servo-Nummer und -Position
+ */
+void rc5_bot_servo(RemCtrlFuncPar *par);
+
+uint16 RC5_Code; /*!< Letzter empfangener RC5-Code */
+
+/*! Fernbedienungsaktionen */
+static RemCtrlAction gRemCtrlAction[] = {
+ /* RC5-Code, Funktion, Parameter */
+ { RC5_CODE_PWR, rc5_emergency_stop, { 0, 0 } },
+ #ifdef BEHAVIOUR_AVAILABLE
+ { RC5_CODE_UP, rc5_bot_change_speed, { 10, 10 } },
+ { RC5_CODE_DOWN, rc5_bot_change_speed, { -10, -10 } },
+ { RC5_CODE_LEFT, rc5_bot_change_speed, { 0, 10 } },
+ { RC5_CODE_RIGHT, rc5_bot_change_speed, { 10, 0 } },
+ #endif
+
+ { RC5_CODE_0, rc5_number, { 0, 0 } },
+ { RC5_CODE_1, rc5_number, { 1, 1 } },
+ { RC5_CODE_2, rc5_number, { 2, 2 } },
+ { RC5_CODE_3, rc5_number, { 3, 3 } },
+ { RC5_CODE_4, rc5_number, { 4, 4 } },
+ { RC5_CODE_5, rc5_number, { 5, 5 } },
+ { RC5_CODE_6, rc5_number, { 6, 6 } },
+ { RC5_CODE_7, rc5_number, { 7, 7 } },
+ { RC5_CODE_8, rc5_number, { 8, 8 } },
+ { RC5_CODE_9, rc5_number, { 9, 9 } },
+ { RC5_CODE_I_II, rc5_bot_next_behaviour, { 0, 0 } },
+#ifdef BEHAVIOUR_SERVO_AVAILABLE
+ { RC5_CH_PLUS, rc5_bot_servo, { SERVO1, DOOR_CLOSE } },
+ { RC5_CH_MINUS, rc5_bot_servo, { SERVO1, DOOR_OPEN } },
+#endif
+#ifdef DISPLAY_SCREENS_AVAILABLE
+ { RC5_CODE_RED, rc5_screen_set, { 0, 0 } },
+ { RC5_CODE_GREEN, rc5_screen_set, { 1, 0 } },
+ { RC5_CODE_YELLOW, rc5_screen_set, { 2, 0 } },
+ { RC5_CODE_BLUE, rc5_screen_set, { 3, 0 } },
+ { RC5_CODE_TV_VCR, rc5_screen_set, { DISPLAY_SCREEN_TOGGLE, 0 } },
+#endif
+#ifdef JOGDIAL
+ { RC5_CODE_JOG_MID, rc5_bot_set_speed, { BOT_SPEED_MAX, BOT_SPEED_MAX } },
+ { RC5_CODE_JOG_L1, rc5_bot_set_speed, { BOT_SPEED_FAST, BOT_SPEED_MAX } },
+ { RC5_CODE_JOG_L2, rc5_bot_set_speed, { BOT_SPEED_NORMAL, BOT_SPEED_MAX } },
+ { RC5_CODE_JOG_L3, rc5_bot_set_speed, { BOT_SPEED_SLOW, BOT_SPEED_MAX } },
+ { RC5_CODE_JOG_L4, rc5_bot_set_speed, { BOT_SPEED_STOP, BOT_SPEED_MAX } },
+ { RC5_CODE_JOG_L5, rc5_bot_set_speed, { -BOT_SPEED_NORMAL, BOT_SPEED_MAX } },
+ { RC5_CODE_JOG_L6, rc5_bot_set_speed, { -BOT_SPEED_FAST, BOT_SPEED_MAX } },
+ { RC5_CODE_JOG_L7, rc5_bot_set_speed, { -BOT_SPEED_MAX, BOT_SPEED_MAX } },
+ { RC5_CODE_JOG_R1, rc5_bot_set_speed, { BOT_SPEED_MAX, BOT_SPEED_FAST } },
+ { RC5_CODE_JOG_R2, rc5_bot_set_speed, { BOT_SPEED_MAX, BOT_SPEED_NORMAL } },
+ { RC5_CODE_JOG_R3, rc5_bot_set_speed, { BOT_SPEED_MAX, BOT_SPEED_SLOW } },
+ { RC5_CODE_JOG_R4, rc5_bot_set_speed, { BOT_SPEED_MAX, BOT_SPEED_STOP } },
+ { RC5_CODE_JOG_R5, rc5_bot_set_speed, { BOT_SPEED_MAX, -BOT_SPEED_NORMAL } },
+ { RC5_CODE_JOG_R6, rc5_bot_set_speed, { BOT_SPEED_MAX, -BOT_SPEED_FAST } },
+ { RC5_CODE_JOG_R7, rc5_bot_set_speed, { BOT_SPEED_MAX, -BOT_SPEED_MAX } }
+#endif /* JOGDIAL */
+};
+
+/*!
+ * Diese Funktion setzt das Display auf eine andere Ausgabe.
+ * Fuer die Verhaltensausgabe werden hier die Verhalten durchgeblaettert
+ * @param par Parameter mit dem zu setzenden Screen.
+ */
+#ifdef DISPLAY_SCREENS_AVAILABLE
+static void rc5_screen_set(RemCtrlFuncPar *par) {
+ if (par) {
+ if (par->value1 == DISPLAY_SCREEN_TOGGLE) {
+
+ #ifdef DISPLAY_BEHAVIOUR_AVAILABLE
+ /* erst nachsehen, ob noch weitere Verhalten auf anderen Pages vorhanden sind */
+ /* nur neuer Screen, wenn alle Verhalten angezeigt wurden */
+ if ((display_screen == 2) && (another_behaviour_page())
+ )
+ behaviour_page++;
+ else {
+ display_screen ++;
+
+ if (display_screen == 1) {
+ behaviour_page = 1;
+ #ifndef DISPLAY_DYNAMIC_BEHAVIOUR_AVAILABLE
+ set_behaviours_equal();
+ #endif
+ }
+
+ }
+
+ #else
+ display_screen ++;
+ #endif
+
+
+ }
+ else
+ {
+ /* Screen direkt waehlen */
+ #ifdef DISPLAY_BEHAVIOUR_AVAILABLE
+
+ /* Screen direkt waehlen und Verhaltens-Puffervariablen abgleichen*/
+ display_screen = par->value1;
+
+ // bei dyn. Anzeige und Auswahl keine Ubernahme in Puffervariable benoetigt
+ #ifndef DISPLAY_DYNAMIC_BEHAVIOUR_AVAILABLE
+ if ((display_screen == 2)&& (behaviour_page == 1)) {
+ set_behaviours_equal();
+ }
+ #endif
+ behaviour_page = 1;
+
+ #else
+ /* Screen direkt waehlen */
+ display_screen = par->value1;
+ #endif
+ }
+
+
+ display_screen %= DISPLAY_SCREENS;
+ display_clear();
+
+ }
+}
+#endif
+
+#ifdef BEHAVIOUR_SERVO_AVAILABLE
+ /*! Steuert den Servo an
+ * @param par Parameter mit Servo-Nummer und -Position
+ */
+ void rc5_bot_servo(RemCtrlFuncPar *par){
+ bot_servo(0,par->value1,par->value2);
+ }
+#endif
+/*!
+ * Diese Funktion wechselt zwiaschen verschiednen Verhalten
+ * @param par Parameter mit den zu setzenden Geschwindigkeiten.
+ */
+void rc5_bot_next_behaviour(RemCtrlFuncPar *par) {
+
+ static uint8 state =0;
+
+ state++;
+
+ switch (state) {
+ case 0:
+ break;
+ #ifdef BEHAVIOUR_DRIVE_SQUARE_AVAILABLE
+ case 1: activateBehaviour(bot_drive_square_behaviour);
+ break;
+ #endif
+ case 2:
+ #ifdef BEHAVIOUR_DRIVE_SQUARE_AVAILABLE
+ deactivateBehaviour(bot_drive_square_behaviour);
+ #endif
+ #ifdef BEHAVIOUR_GOTO_AVAILABLE
+ deactivateBehaviour(bot_goto_behaviour);
+ #endif
+ #ifdef BEHAVIOUR_OLYMPIC_AVAILABLE
+ activateBehaviour(bot_olympic_behaviour);
+ #endif
+ break;
+ default:
+ #ifdef BEHAVIOUR_DRIVE_DISTANCE_AVAILABLE
+ deactivateBehaviour( bot_drive_distance_behaviour);
+ #endif
+ #ifdef BEHAVIOUR_TURN_AVAILABLE
+ deactivateBehaviour( bot_turn_behaviour);
+ #endif
+ #ifdef BEHAVIOUR_OLYMPIC_AVAILABLE
+ deactivateBehaviour(bot_olympic_behaviour);
+ deactivateBehaviour( bot_explore_behaviour);
+ deactivateBehaviour( bot_do_slalom_behaviour);
+ #endif
+
+ state=0;
+ }
+}
+
+#ifdef JOGDIAL
+/*!
+ * Diese Funktion setzt die Geschwindigkeit auf den angegebenen Wert.
+ * @param par Parameter mit den zu setzenden Geschwindigkeiten.
+ */
+static void rc5_bot_set_speed(RemCtrlFuncPar *par) {
+ if (par) {
+ target_speed_l = par->value1;
+ target_speed_r = par->value2;
+ }
+}
+#endif
+
+/*!
+ * Diese Funktion stellt die Not-Aus-Funktion dar. Sie laesst den Bot anhalten
+ * und setzt alle Verhalten zurueck mit Sicherung der vorherigen Aktivitaeten.
+ * @param par notwendiger Dummy-Parameter.
+ */
+ static void rc5_emergency_stop(RemCtrlFuncPar *par) {
+ #ifdef BEHAVIOUR_AVAILABLE
+ // Setzen der Geschwindigkeit auf 0
+ target_speed_l = 0 ;
+ target_speed_r = 0 ;
+
+ // Alle Verhalten deaktivieren
+ deactivateAllBehaviours(); // alle Verhalten deaktivieren mit vorheriger Sicherung
+ #ifdef DISPLAY_BEHAVIOUR_AVAILABLE
+ // bei dynamischer Verhaltensanzeige kein Sprung in Anzeigescreen
+ #ifndef DISPLAY_DYNAMIC_BEHAVIOUR_AVAILABLE
+ display_clear(); // Screen zuerst loeschen
+ display_screen = 2; // nach Notstop in den Verhaltensscreen mit Anzeige der alten Verhalten
+ #endif
+ #endif
+ #endif
+}
+
+/*!
+ * Diese Funktion aendert die Geschwindigkeit um den angegebenen Wert.
+ * @param par Parameter mit den relativen Geschwindigkeitsaenderungen.
+ */
+#ifdef BEHAVIOUR_AVAILABLE
+ static void rc5_bot_change_speed(RemCtrlFuncPar *par) {
+ int old;
+ if (par) {
+ old=target_speed_l;
+ target_speed_l += par->value1;
+ if ((target_speed_l < -BOT_SPEED_MAX)|| (target_speed_l > BOT_SPEED_MAX))
+ target_speed_l = old;
+
+ old=target_speed_r;
+ target_speed_r += par->value2;
+ if ((target_speed_r <-BOT_SPEED_MAX)||(target_speed_r > BOT_SPEED_MAX))
+ target_speed_r = old;
+ }
+ }
+#endif
+
+/*!
+ * Liest ein RC5-Codeword und wertet es aus
+ */
+void rc5_control(void){
+ uint16 run;
+ static uint16 RC5_Last_Toggle = 1; /*!< Toggle-Wert des zuletzt empfangenen RC5-Codes*/
+
+ uint16 rc5 = ir_read();
+
+ if (rc5 != 0) {
+ RC5_Code= rc5 & RC5_MASK; /* Alle uninteressanten Bits ausblenden */
+ /* Toggle kommt nicht im Simulator, immer gewechseltes Toggle Bit sicherstellen */
+ #ifdef PC
+ RC5_Last_Toggle = !(rc5 & RC5_TOGGLE);
+ #endif
+ /* Bei Aenderung des Toggle Bits, entspricht neuem Tastendruck, gehts nur weiter */
+ if ((rc5 & RC5_TOGGLE) != RC5_Last_Toggle) { /* Nur Toggle Bit abfragen, bei Ungleichheit weiter */
+ RC5_Last_Toggle = rc5 & RC5_TOGGLE; /* Toggle Bit neu belegen */
+
+ /* Suchen der auszufuehrenden Funktion */
+ for(run=0; run<sizeof(gRemCtrlAction)/sizeof(RemCtrlAction); run++) {
+ /* Funktion gefunden? */
+ if (gRemCtrlAction[run].command == RC5_Code) {
+ /* Funktion ausfuehren */
+ gRemCtrlAction[run].func(&gRemCtrlAction[run].par);
+ }
+ }
+ }
+ }
+}
+
+#ifdef DISPLAY_BEHAVIOUR_AVAILABLE
+/*!
+ * toggled ein Verhalten der Verhaltensliste an Position pos,
+ * die Aenderung erfolgt nur auf die Puffervariable
+ * @param i Verhaltens-Listenposition, entspricht der Taste 1-6 der gewaehlten Verhaltensseite
+ */
+ void rc5_toggle_behaviour_new(int8 i) {
+
+ toggleNewBehaviourPos(i);
+ }
+
+/*!
+ * Diese Funktion setzt die Aktivitaeten der Verhalten nach der Auswahl.
+ * Hierdurch erfolgt der Startschuss fuer Umschaltung der Verhalten
+ * nicht verwendet bei sofortiger Anzeige und Auswahl der Aktivitaet
+ */
+ #ifndef DISPLAY_DYNAMIC_BEHAVIOUR_AVAILABLE
+ static void rc5_set_all_behaviours(void) {
+
+ set_behaviours_active_to_new();
+
+ }
+ #endif
+#endif
+
+/*!
+ * Verarbeitet die Zifferntasten in Abhaengigkeit vom eingestelltem Screen
+ * @param par Parameter mit der betaetigten Zahlentaste.
+ */
+void rc5_number(RemCtrlFuncPar *par) {
+ #ifdef DISPLAY_SCREENS_AVAILABLE
+ switch (display_screen) {
+ #ifdef DISPLAY_BEHAVIOUR_AVAILABLE
+ case 2:
+ switch (par->value1) {
+ case 0: break;
+ case 1: rc5_toggle_behaviour_new(1); break;
+ case 2: rc5_toggle_behaviour_new(2); break;
+ case 3: rc5_toggle_behaviour_new(3); break;
+ case 4: rc5_toggle_behaviour_new(4); break;
+ case 5: rc5_toggle_behaviour_new(5); break;
+ case 6: rc5_toggle_behaviour_new(6); break;
+ case 7: break;
+ case 8: break;
+ case 9:
+ #ifndef DISPLAY_DYNAMIC_BEHAVIOUR_AVAILABLE
+ rc5_set_all_behaviours();
+ #endif
+ break;
+ }
+ break;
+ #endif
+ default:
+ #endif
+ switch (par->value1) {
+ #ifdef BEHAVIOUR_AVAILABLE
+ case 0:
+ target_speed_l=0;target_speed_r=0;break;
+ case 1: target_speed_l = BOT_SPEED_SLOW; target_speed_r = BOT_SPEED_SLOW; break;
+ #endif
+ #ifdef BEHAVIOUR_DRIVE_DISTANCE_AVAILABLE
+ case 2: bot_drive_distance(0, 0, BOT_SPEED_NORMAL, 10); break;
+ #endif
+ // case 3: target_speed_l = BOT_SPEED_NORMAL; target_speed_r = BOT_SPEED_NORMAL; break;
+ #ifdef MAP_AVAILABLE
+ case 3: print_map(); break;
+ #endif
+// case 4: bot_turn(0, 90); break;
+ #ifdef BEHAVIOUR_SCAN_AVAILABLE
+ case 4: bot_scan(0); break;
+ #endif
+// //case 5: bot_goto(0, 0, 0); break;
+// #ifdef MEASURE_MOUSE_AVAILABLE
+// case 5: bot_gotoxy(0,20,20);
+// #else
+
+ case 5: remote_call_list(); break;
+
+
+ #ifdef BEHAVIOUR_SOLVE_MAZE_AVAILABLE
+// case 5: bot_solve_maze(0); break;
+ #endif
+ #ifdef BEHAVIOUR_CATCH_PILLAR_AVAILABLE
+// case 5: bot_catch_pillar(0); break;
+ #endif
+
+// case 5: target_speed_l = BOT_SPEED_MAX; target_speed_r = BOT_SPEED_MAX; break;
+// #endif
+// case 5: bot_scan(0); break;
+ #ifdef BEHAVIOUR_TURN_AVAILABLE
+ case 6: bot_turn(0, -90); break;
+ case 7: bot_turn(0,180); break;
+ case 9: bot_turn(0, -180); break;
+ #endif
+ #ifdef BEHAVIOUR_DRIVE_DISTANCE_AVAILABLE
+ case 8: bot_drive_distance(0, 0, BOT_SPEED_NORMAL, 10); break;
+ #endif
+
+// case 0: target_speed_l=BOT_SPEED_STOP;target_speed_r=target_speed_l;break;
+// case 1: target_speed_l=BOT_SPEED_SLOW;target_speed_r=target_speed_l;break;
+// case 2: target_speed_l=BOT_SPEED_MEDIUM;target_speed_r=target_speed_l;break;
+// case 3: target_speed_l=BOT_SPEED_FAST;target_speed_r=target_speed_l;break;
+// case 4: target_speed_l=BOT_SPEED_MAX;target_speed_r=target_speed_l;break;
+
+// case 5: Kp++; break;
+// case 8: Kp--; break;
+// case 6: Ki++; break;
+// case 9: Ki--; break;
+
+// case 9: target_speed_l=-BOT_SPEED_MEDIUM;target_speed_r=target_speed_l;break;
+ }
+ #ifdef DISPLAY_SCREENS_AVAILABLE
+
+ break;
+
+ }
+ #endif
+ }
+#endif