m3pi logo

An introduction to logo

Aims of the m3pi-logo project

This page will be devoted to the development and advancement of the m3pi robot for use with the logo functional programming language. The aim will be to control the full functionality of the m3pi robot through a text file that can be located on a flash/thumb drive. Users can simply write their code into the text file from a computer and then run it on the m3pi. I hope to keep what code is recognised and understood and indeed what is used as similar to the actual Logo language as possible so that it may be used as a more physical demonstration for those that studying or are looking to study the language. However there may be a few new additions...

Basic Logo language

The commands set forth are simple to understand and need nothing in the way of conventional programmers understanding. The object that is doing the actual moveing has become known as the Turtle through visualization and debugging software.

  • FORWARD 100
    • This makes the 'turtle' move forward 100 units (in this case, centimetres)
  • BACKWARD 100
    • This makes it move backward 100 units
  • RIGHT 90
    • A rotation to the right 90° although at present i have narrowed down the precise accuracy to within 5° to 10°
  • LEFT 20
    • A rotation to the left by 20°
  • REPEAT 4
    [FORWARD 10 RIGHT 90]
    • This will repeat anything within the brackets the number of times stated outside (in this case, repeat the commands forward 10cm and right 90° four times)
    • on closer inspection, this may take some doing. But I shall try...
      • UPDATE it can be done! however I shall have to deviate from the conventional Logo language and have the REPEAT 4 on a separate line to the actual thing than is to be repeated (including square brackets)

Above is stated the commands that exist already in Logo, but we have some more things we can do, what with being a robot and all...

  • BUZZER 100
    • This will make the yet unused (and undisclosed) buzzer on the m3pi make a sound at the intended frequency.
    • NOTE there is no time limit to this, but your m3pi will not move or function whilst making the sound.
  • BUZZER 0
    • This will turn the buzzer off, and allow normal operation of the m3pi to resume
  • STOP 10
    • This will stop the m3pi from moving, but not stop the buzzer from sounding. can be used as a wait command to hold or pause the m3pi for a set duration. As of yet it is undecided if it will be in seconds or milliseconds

The concept

The idea whilst being simple in nature: to convert the logo visual programming language into a set of commands that the mbed and m3pi can recognise, isn't without it's difficulties. For starters, one must grab all of the content of a text document (there have also been suggestions of doing it through a hyper terminal) and then process it into it's components; the action, and the variable associated with it.

Getting started

First we need to insure everything is working properly for this we can use a simple code to read a text file on a memory stick called YourText.txt and print the first 8 characters of the document to the m3pi's LCD screen (8 characters because that is all that can fit on the first line of the display)

Hello_World

#include "mbed.h"
#include "m3pi.h"
#include "MSCFileSystem.h"

DigitalOut myled(LED1);
m3pi m3pi;
MSCFileSystem msc("usb");

//The m3pi can have a maximum of 8 charicters on a row of it's display, so logically that is all we need to accomedate
char YourText[8];

int main() {
    //set the file you want to open to /usb/YourFile.txt and we want to read it, so fopen needs 'r'
    FILE *YourFile = fopen("/usb/YourFile.txt", "r");
    if (YourFile == NULL) {
        //if your file isnt there, turn an led on and do nothing else
        myled = 1;
        while (1) {}
    }
    //scan untill you hit then end of the document and put everything in YourText as a string
    while (!feof(YourFile)) {
        fscanf (YourFile, "%s", YourText);
    }
    m3pi.cls();
    //and print your message!
    m3pi.printf("%s", YourText);
}

Import programm3pi_Logo_HelloWorld

This simple program will test the functionality of the m3pi\'s usb port by reading a file on a usb flash drive (called YourText.txt) and printing it to the m3pi\'s inbuilt LCD display.

YourFile.txt on a flash disc

Simply have the YourText.txt file under the main directory of your device, and it should work

Hi world


Now all that may be good for testing you m3pi works, but doesn't get us far in the way of understanding or processing it although we can use a similar fscanf command. Below is a program that demonstrates (in long) how one may do this if you are looking at it character by character. It isn't very practical but it demonstrates the principle of how you could attain the goal. (I have not included the whole program below, but the relevant recognition steps. for full code, see below)

m3pi_recognition_principle

/* Assuming that we have fscanf'd the content of out command file into Buffer, we can do the following:*/

void recognition() {
    //this shall be used to incriment what character we are looking at
    int N=2;
    //repeat until the end of the document
    while (!feof(CMD)) {
        if (Buffer[N] == 'F' || Buffer[N] == 'f') {
            N++;
            //Because it's a  string, the conversion will turn the number 1 into 49, as it is the 49th character that can be recognised.
            while (Buffer[N] >= 48) {               
                m3pi.cls();
                m3pi.printf("FWD %c", Buffer[N]);   // F represents forward and
                m3pi.forward(speed_max);            // a number after it represents how long
                wait(Buffer[N] - 48);               //to go forwards for. this senario
                m3pi.stop();                        //only includes the posibilty of
                N++;                                // a one digit number.
            }
        } else if (Buffer[N] == 'B' || Buffer[N] == 'b') {
            N++;
            while (Buffer[N] >= 48) {
                m3pi.cls();
                m3pi.printf("BACK %c", Buffer[N]);
                m3pi.backward(speed_max);
                wait(Buffer[N] - 48);
                N++;
            }
        } else if (Buffer[N] == 'R' || Buffer[N] == 'r') {
            N++;
            while (Buffer[N] >= 48) {
                int A=Buffer[N] - 48;
                m3pi.cls();
                m3pi.printf("RGHT %d", A);
                m3pi.left( - speed_max);
                m3pi.right(speed_max);
                wait(((speed_mod * 0.28)/9)*A); //a number after R or L represents
                m3pi.stop();                    //how much to turn. the algorithm
                N++;                            //above converts that to wait times for motors
            }
        } else if (Buffer[N] == 'L' || Buffer[N] == 'l') {
            N++;
            while (Buffer[N] >= 48) {
                int A=Buffer[N] - 48;
                m3pi.cls();
                m3pi.printf("LFT %d", A);
                m3pi.right( - speed_max);
                m3pi.left(speed_max);
                wait(((speed_mod * 0.28)/9)*A);
                m3pi.stop();
                N++;
            }
        } else if (Buffer[N] == 'S' || Buffer[N] == 's') {
            m3pi.cls();
            m3pi.printf("STOP");
            m3pi.stop();
            FIN();
            N++;
            //if there is a * then we have reached the end of what is in Buffer
        } else if (Buffer[N] == '*') {
            m3pi.stop();
            m3pi.cls();
            m3pi.printf("FIN!");
            FIN();
            //if there is a character that is not listed above, it is probebly an error
        } else {
            m3pi.stop();
            m3pi.cls();
            m3pi.printf("  ERR  ");
            ERR();
        }
    }
}


Import programM3pi_logo_principle

M3pi logo character recognition principle



As I have stated, this program is far from ideal, but if you are struggling to understand the consent, it can help.

The repeat command

Unfortunately, to have the repeat command and the actual repeated commands on the same line would prove difficult to dissect and run, it would also mean that you would also have to declare a repeat command every line. So as a compromise the repeated commands will go on a septate line. This makes detecting the repeat command much easier, we can use the parser. But we also need to detect the things we want to repeat, for this we could either guess the number of things there will be, or we can use strtok to split the commands within the square brackets into their individual commands, with no variables or white spaces in there. Once this is done, we have to enter a for loop that will repeat everything the number of times that was discovered in the first parser. within that we also need another for loop that will scanf the string with the commands to be repeated and carry them out (basically, another parser within a for loop, within a for loop within a parser. I had a real headache working this out)
This diagram should help:
/media/uploads/Nicholas/repeat_consept.png

(Thanks to Charles for checking this)


All wikipages