A Robotics Project Page
Google
 
Web    www.PhilBot.com
My other sites
  • OurCoolHouse
  • Phil's Resume
  • Web Portfolio

  • [Home] [Projects] [Hardware] [Software] [Books] [Links] [Downloads]


    PBot_Sumo_VC.  Examples of using the MkIII oUserClass for Sumo

    On my [PBot_MkIII_VC] page I describe the inner workings of the OOPic oUserClass I created to control the Mark III Mini-Sumo robot.  This class doesn't actually do Sumo, it just provides all the important interfaces in one central location.  The reason that the UserClass doesn't actually make any Sumo decisions is that I want to try out different strategies, so the "fighting intelligence" is left outside of the class itself.

    My various sample programs are located on the [downloads] page, and my most basic of all Sumo programs is called PBot_Sumo_VC1.osc

    With the OOPic compiler, the way you use an oUserClass is to declare an object and pass it the file name of the program that contains the UserClass.    In my case the Class file is called:  PBot_MkIII_VC.osc  On my PC, I have a main folder under the C: drive called OOPIC, and another one under that called SUMO, so the full path is C:\OOPIC\SUMO\PBot_MkIII_VC.osc

    Here is what the code looks like to reference my User class.  Keep in mind I'm using the C syntax.

    // Create instance of MKIII Object.
    // Note: Make sure the path matches your file's location.
    oUserClass MkIII = New oUserClass ("C:\OOPIC\SUMO\PBot_MkIII_VC.osc");

    So now to use this class I simply need to prefix the class' variables and functions with "MkIII.".

    OK, so let's focus on what a Sumo has to do. 

    1. Wait five seconds before moving.
    2. Locate it's opponent and push them out of the ring.

    That's pretty straight forward, especially with my MkIII User class.  So, what I'll do is setup a timer to count down 5 seconds.  While it's counting down, I'll calibrate my White Line sensors to make sure I can see the ring border.  Once the timer runs out I'll engage the Servos and play Sumo.  So here's the first part of the program...  The countdown and calibration.

    // Create motion constants
    Const FAST_FORWARD     = 10;
    Const SLOW_FORWARD     = 1;
    Const FAST_REVERSE     = -10;
    Const FAST_RIGHT       = 10;
    Const FAST_LEFT        = -10;

    // --------------------------------
    // setup the Action Timer for 1/10th Second ticks
    // Preload counter with 5 second delay
    // --------------------------------
    oCountDownO ActionTimer = New oCountDownO;

    ActionTimer.PreScale = 5;
    ActionTimer.ClockIn.Link(ooPIC.Hz60);
    ActionTimer          = 50;
    ActionTimer.Operate  = cvTrue;

    // Count down to 1 second then Calibrate line sensors
    While(ActionTimer > 10) ;
    MkIII.CalibrateLine;

    // Wait for last second to expire
    While(ActionTimer.NonZero) ;

    // Enable Servo drive
    MkIII.StartServos;
     

    Notice the two places I made calls into the MkIII object.  Once to calibrate the line sensors, and once to turn on the servos.  Notice that there is nowhere in my code where I need to setup the servos or sensors or any of those things.  The MkIII oUserClass does it all for me.

    Now that I'm ready to go, I'm going to drop into a loop that runs forever.  Inside that loop I'm going to test the various MkIII status flags to see what action I need to take.  I've arranged the program into a series of If / Else statements.  I do the highest priority tests first, and then if that condition isn't met, I drop down to the next lower priority tests.  Finally if there are no actions to take, I just drive forward until something happens.

    PBot_Sumo_VC1 is what I call "Strategy 1: Defensive Stance". There are three basic priorities:

    1. Avoid the edge at all cost (Line Avoidance)
    2. Find and follow the opponent (Attack)
    3. Drive Forward (Seek)

    Here is the code that executes these priorities:

    // Repeat main program loop forever.
    While (cvTrue)
    {
        // Run down the SUMO priority list

        // Priority 1: Avoiding the border
        If (MkIII.LeftLineOn | MkIII.CenterLineOn)
        {
            // If we see the left line, backup & Spin right 180
            MkIII.Forward(FAST_REVERSE);
            ooPIC.Delay = 25;
            MkIII.Spin(FAST_RIGHT);
            ooPIC.Delay = 45;
        }
        Else If (MkIII.RightLineOn)
        {
            // If we see the right line, backup and spin left 180
            MkIII.Forward(FAST_REVERSE);
            ooPIC.Delay = 25;
            MkIII.Spin(FAST_LEFT);
            ooPIC.Delay = 45;
        }

        // Priority 2: Follow the opponent
        Else If (MkIII.BothEyesOn)
        {
            // Go forward
            MkIII.Forward(FAST_FORWARD);
        }
        Else If (MkIII.RightEyeOn)
        {
            // Turn right towards the target
            MkIII.Drive(SLOW_FORWARD,FAST_RIGHT);
        }
        Else If (MkIII.LeftEyeOn)
        {
            // Turn left towards the target
            MkIII.Drive(SLOW_FORWARD,FAST_LEFT);
        }

        // Priority 3: Go Forward
        Else
        {
            // Go forward
            MkIII.Forward(FAST_FORWARD);
        }
    }

    And that's pretty much it.  The real simplification here is that it's easy to test the Sumo's state just by checking the various "On" bits.

    OK, what's wrong with this basic Sumo strategy?  Well, the first thing that smart sumo builders did was to take advantage of this "defensive" strategy.  They added a small white lip to the front of their wedge, so if their opponent saw it, they thought they were on the white line and they immediately backed up.  This was a great way to cause you opponent to just back out of the ring.  So to overcome this, a new strategy was needed.  I call this Strategy 2: Aggressive Stance.  This strategy adds a new priority higher than the Line Avoidance rule, and this is: "If you can see the opponent with both eyes, ignore the line, and push forward".  Here are the priorities:

    1. If the opponent is directly in front of you, push forward (Attack)
    2. Avoid the edge (Line Avoidance)
    3. Turn towards the opponent (Track)
    4. Drive Forward (Seek)

    The possible down side of this strategy is if the SumoBot sees something outside the ring, it may just drive right off the edge.  For this reasons it's important to play strictly by the rules and insist that Bot owners step away from the ring during a match.  Here is the code for this strategy.  It's on the  [downloads] page as PBot_Sumo_VC2.osc

    // Repeat main program loop forever.
    While (cvTrue)
    {
        // Run down the SUMO priority list

        // Priority 1: Push the opponent
        If (MkIII.BothEyesOn)
        {
            // Go forward
            MkIII.Forward(FAST_FORWARD);
        }

        // Priority 2: Avoid the border
        Else If (MkIII.LeftLineOn | MkIII.CenterLineOn)
        {
            // If we see the left line, backup & Spin right 180
            MkIII.Forward(FAST_REVERSE);
            ooPIC.Delay = 25;
            MkIII.Spin(FAST_RIGHT);
            ooPIC.Delay = 45;
        }
        Else If (MkIII.RightLineOn)
        {
            // Backup and spin left 180
            MkIII.Forward(FAST_REVERSE);
            ooPIC.Delay = 25;
            MkIII.Spin(FAST_LEFT);
            ooPIC.Delay = 45;
        }

        // Priority 3: Turn towards the opponent
        Else If (MkIII.RightEyeOn)
        {
            // Turn right towards the target
            MkIII.Drive(SLOW_FORWARD,FAST_RIGHT);
        }
        Else If (MkIII.LeftEyeOn)
        {
            // Turn left towards the target
            MkIII.Drive(SLOW_FORWARD,FAST_LEFT);
        }

        // Priority 4: Go Forward
        Else
        {
            // Go forward
            MkIII.Forward(FAST_FORWARD);
        }
    }
     

    Why not download these samples and see what other strategies you can invent for making your Sumo just a bit smarter than the next guy's.

     

    Web content is copyright © PhilBot.com 2005, Deep Creek Lake, MD.
    Contact: Phil Malone 301.387.2331, webmaster@PhilBot.com