Look for a LOGO (.LGO) file on the mbed and run the commands in it. Only supports a small subset of the LOGO commands.

Dependencies:   mbed

Revision:
0:864f6ee5169b
diff -r 000000000000 -r 864f6ee5169b commands.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commands.cpp	Sat Apr 09 18:06:27 2011 +0000
@@ -0,0 +1,284 @@
+/*
+ * LOGO command implementation
+ */
+ 
+#include "mbed.h"
+#include "m3pi.h"
+
+#include "commands.h"
+#include "tokens.h"
+
+extern m3pi m3pi;
+
+// Speed at which the tutle moves...
+static const float SPEED = 0.25;
+
+// Adjustment needed for rotation...
+static const float ROTATION_ADJUST = 1.1;
+
+/*  ======================================================================
+    FORWARD
+    ====================================================================== */
+
+struct ForwardCommand : public Command
+{
+    ForwardCommand(int steps) : steps_(steps) {}
+    virtual ~ForwardCommand() {}
+    
+    virtual void go() const {
+        // Robot goes forward 470mm per second at half speed. We need to 
+        // convert this into steps.
+        //
+        // Full speed (1.0) is 940mm per second, a step of 47 gives us 20
+        // steps per second at full speed.
+        //
+        static const float STEP_TIME = 0.05 / SPEED;
+        m3pi.forward(SPEED);
+        wait(STEP_TIME * steps_);
+        m3pi.forward(0.0);
+    }
+    
+    virtual const char* string() const {
+        static char buf[256];
+        sprintf(buf, "FD %d", steps_);
+        return buf;
+    }
+    
+private:
+    int steps_;
+};
+
+static Command* build_forward_command(const char* str, int* pos) {
+    Token token;
+    get_token(&token, str, pos);
+    if (token.isInteger()) {
+        int steps = token.getInteger();
+        return new ForwardCommand(steps);
+    }
+    return NULL;
+}
+
+/*  ======================================================================
+    BACK
+    ====================================================================== */
+
+struct BackCommand : public Command
+{
+    BackCommand(int steps) : steps_(steps) {}
+    virtual ~BackCommand() {}
+    
+    virtual void go() const {
+        // Robot goes forward 470mm per second at half speed. We need to 
+        // convert this into steps.
+        //
+        // Full speed (1.0) is 940mm per second, a step of 47 gives us 20
+        // steps per second at full speed.
+        //
+        static const float STEP_TIME = 0.05 / SPEED;
+        m3pi.backward(SPEED);
+        wait(STEP_TIME * steps_);
+        m3pi.backward(0.0);
+    }
+    
+    virtual const char* string() const {
+        static char buf[256];
+        sprintf(buf, "BK %d", steps_);
+        return buf;
+    }
+    
+private:
+    int steps_;
+};
+
+static Command* build_back_command(const char* str, int* pos) {
+    Token token;
+    get_token(&token, str, pos);
+    if (token.isInteger()) {
+        int steps = token.getInteger();
+        return new BackCommand(steps);
+    }
+    return NULL;
+}
+
+/*  ======================================================================
+    LEFT
+    ====================================================================== */
+
+struct LeftCommand : public Command
+{
+    LeftCommand(int angle) : angle_(angle) {}
+    virtual ~LeftCommand() {}
+    
+    virtual void go() const {
+        // Robot rotates 720 degrees per second at half speed.
+        //
+        // So full speed (1.0) is 1440 degrees per second, and 1 degree is
+        // 1.0 / 1440
+        //
+        static const float DEGREE = (1.0 / 1440) / SPEED;
+        m3pi.left(SPEED);
+        wait(DEGREE * angle_ * ROTATION_ADJUST);
+        m3pi.left(0.0);
+    }
+    
+    virtual const char* string() const {
+        static char buf[256];
+        sprintf(buf, "LT %d", angle_);
+        return buf;
+    }
+    
+private:
+    int angle_;
+};
+
+static Command* build_left_command(const char* str, int* pos) {
+    Token token;
+    get_token(&token, str, pos);
+    if (token.isInteger()) {
+        int angle = token.getInteger();
+        return new LeftCommand(angle);
+    }
+    return NULL;
+}
+
+/*  ======================================================================
+    RIGHT
+    ====================================================================== */
+
+struct RightCommand : public Command
+{
+    RightCommand(int angle) : angle_(angle) {}
+    virtual ~RightCommand() {}
+    
+    virtual void go() const {
+        // Robot rotates 720 degrees per second at half speed.
+        //
+        // So full speed (1.0) is 1440 degrees per second, and 1 degree is
+        // 1.0 / 1440
+        //
+        static const float DEGREE = (1.0 / 1440) / SPEED;
+        m3pi.right(SPEED);
+        wait(DEGREE * angle_ * ROTATION_ADJUST);
+        m3pi.right(0.0);
+    }
+    
+    virtual const char* string() const {
+        static char buf[256];
+        sprintf(buf, "RT %d", angle_);
+        return buf;
+    }
+    
+private:
+    int angle_;
+};
+
+static Command* build_right_command(const char* str, int* pos) {
+    Token token;
+    get_token(&token, str, pos);
+    if (token.isInteger()) {
+        int angle = token.getInteger();
+        return new RightCommand(angle);
+    }
+    return NULL;
+}
+
+/*  ======================================================================
+    PENDOWN
+    ====================================================================== */
+
+struct PenDownCommand : public Command
+{
+    PenDownCommand() {}
+    virtual ~PenDownCommand() {}
+    
+    virtual void go() const {
+    }
+    
+    virtual const char* string() const {
+        return "PD";
+    }
+};
+
+static Command* build_pendown_command(const char* str, int* pos) {
+    return new PenDownCommand();
+}
+
+/*  ======================================================================
+    PENUP
+    ====================================================================== */
+
+struct PenUpCommand : public Command
+{
+    PenUpCommand() {}
+    virtual ~PenUpCommand() {}
+    
+    virtual void go() const {
+    }
+    
+    virtual const char* string() const {
+        return "PU";
+    }
+};
+
+static Command* build_penup_command(const char* str, int* pos) {
+    return new PenUpCommand();
+}
+
+/*  ======================================================================
+    Command Builder
+    ====================================================================== */
+
+typedef Command* build_command_fn(const char* str, int* pos);
+
+static const struct {
+    const char* name;
+    build_command_fn* fn;
+} command_builders[] = {
+    { "FD", build_forward_command },
+    { "FORWARD", build_forward_command },
+    { "BK", build_back_command },
+    { "BACK", build_back_command },
+    { "LT", build_left_command },
+    { "LEFT", build_left_command },
+    { "RT", build_right_command },
+    { "RIGHT", build_right_command },
+    { "PD", build_pendown_command },
+    { "PENDOWN", build_pendown_command },
+    { "PU", build_penup_command },
+    { "PENUP", build_penup_command },
+    { NULL, NULL }
+};
+
+Command* build_command(int line, const char* str, int* pos) {
+    Token token;
+    get_token(&token, str, pos);
+    if (token.isValid()) {
+        if (token.isWord()) {
+            for (int i = 0; command_builders[i].name != NULL; ++i) {
+                if (strcmp(token.getWord(), command_builders[i].name) == 0) {
+                    return command_builders[i].fn(str, pos);
+                }
+            }
+            m3pi.cls();
+            m3pi.printf("BadCmd");
+            m3pi.locate(0,1);
+            m3pi.printf("L%d,C%d", line, *pos);
+        } else if (!token.isEOL()) {
+            m3pi.cls();
+            m3pi.printf("BadToken");
+            m3pi.locate(0,1);
+            m3pi.printf("L%d,C%d", line, *pos);
+        }
+    } else {
+        m3pi.cls();
+        m3pi.printf("UnkToken");
+        m3pi.locate(0,1);
+        m3pi.printf("L%d,C%d", line, *pos);
+    }
+    return NULL;
+}
+
+void destroy_command(Command* cmd) {
+    delete cmd;
+}
+