• Software

    Software


    Interactive C


    The development tool for the used for the The Handy Board is called Interactive C (IC). IC is basically consist of two parts, a pseudo-code (pcode) machine language module and the interface/compiler portion (IC program).

    IC compiles into pseudo-code (p-code) which is then executed by a custom stack machine. The p-code is interpreted by a run-time machines language program store in the 6811 MPU. This unique approach was taken because it allows IC to have run-time error check, small object code, source code portability and finally the most useful and powerful feature, multi tasking. The only drawback is at the expense of slower execution speed. However, this should not be a problem with most applications.

    IC supports a subset of C, it includes:

    Here is a block diagram of how IC works.

    IC Library functions


    DC Motors

    Servo Motor

    Sensor Input

    User Buttons and Knob

    Infrared Subsystem

    Time Commands

    Tone Functions

    Multi-Tasking

    Floating Point Functions

    Memory Access Functions

    Here is an hierarchical sturcture of the IC library functions in relations to user programs.

    Software model


    The main function of the robot is to gather information from all of its sensors and decide what to do from the information collected. It must constantly poll, 4 infrared(edge), 4 ultrasound, and 4 contact sensors. In addition to checking the sensors, the motors are controlled via an open loop system with no feedbacks. Therefore it must use some timing function to control its maneuvers such as turning. The multi-tasking function and time commands of IC seems ideally suited for this application.

    The ellipses are individual tasks. The sensors checking tasks writes the result of its sesnsor test to global variables. The "Main Program" polls these global variables and decides on what to do. It also have to make sure that only one "Move Robot" task can be active at a time. This information is communicated to the "Main Program" via task status global variables.

    
    /*****************************************************
     *****   Dave's Multi-tasking Sumo Robot Program *****
     *****         Version .91   May 18, 97           *****
     *****************************************************/
    
    
    
    /*****************************************************
     **********     Global Variablies       **************
     *****************************************************
     **********   Common fixed values       **************
     *****************************************************/
    int moving=1,
        not_moving=0,
        robot_status,
        running=1,
        not_running=0;
    
    /*****************************************************
     **********          Analog ports        *************
     *****************************************************
     ***********   Infared edge sensors    ***************
     *****************************************************
     ******  Values for edge   ******
     ******    1 = fl_edge     ******
     ******    2 = fr_edge     ******
     ******    4 = rl_edge     ******
     ******    8 = rr_edge     ******/
    
    int rr_edge=0,
        rl_edge=1,
        fr_edge=2,
        fl_edge=3,
        first_edge=0,
        last_edge=3,
        suface_value=0,
        off_edge_value=0,
        white_value=0,
        temp_edge=0,
        edge=0;
    
    /*****************************************************
     **************     Digital Ports      ***************
     *****************************************************/
    int left_ultra=12,
        front_left_ultra=13,
        front_right_ultra14,
        right_ultra=15,
        first_ultra=12,
        last_ultra=15,
        ultra=0,
        temp_ultra=0;
    
    int left_contact=7,
        right_contact=8,
        /*front_contact=xx,
        rear_contact=xx,*/
        first_contact=7,
        last_contact=8,
        contact=0,
        temp_contact=0;
    
    /*****************************************************
     ********  Direction, Speed, and Duration   **********
     *****************************************************/
    int fast=100,
        medium=50,
        slow=11,
        forward=1,
        right=2,
        left=3,
        fast_pivot=100,
        slow_pivot=50,
        reverse=-1;
    
    long forever=255l;
    
    
    /*****************************************************
     *********         Process ID's         **************
     *****************************************************/
    int edge_pid,move_pid,contact_pid,ultra_pid,
        edge_evade_pid,contact_evade_pid,tracking_pid;
    
    
    /*****************************************************
     *********       Process Status         **************
     *****************************************************/
    int edge_status,move_status,ultra_status,contact_evade_status,
        edge_evade_status,tracking_status;
    int edge_evade_stage1=not_running;
    
    
    
    /*****************************************************
     ********      Sensor Checking Taskes      ***********
     *****************************************************
     ******** Edge detection Analog ports 0-3  ***********
     *****************************************************/
    void check_edge()
    {               
      int x,e;
      while(1)
      {  
         e=0;
         for (x=first_edge; x<=last_edge; x++)
         { 
           e <<= 1;    /* shift e 1 bit to the left */
           if (analog(x) <= white_value) /*||analog(x) >= off_edge_value)*/
    	 e |= 1;   /* OR e with 0001 */
         }
         /*printf("edge=%d  e=%d\n",edge,e);*/
         if (e != edge)
           edge=e;
      }
    }   
    
    
    /*****************************************************
     ******  Contact sensors, Digital ports 7-10   *******
     *****************************************************/
    
    void check_contact()
    {               
      int x,c;
      while(1)
      {  
         c=0;
         for (x=first_contact; x<=last_contact; x++)
         { 
           c <<= 1;    /* shift c 1 bit to the left */
           if (digital(x))
    	 c |= 1;   /* OR c with 0001 */
         }
         /*printf("contact=%d  c=%d\n",contact,c);*/
         if (c != contact)
           contact=c;
      }
    }
    
    /*****************************************************
     ****** Obstacle detection Digital ports 12-15 *******
     *****************************************************/
    
    void check_ultra()
    {
      int u,x,y,z;
      while (1)
      {
        u=0;
        for(x=first_ultra; x<=last_ultra; x++) /* left to right */
        {
          u <<= 1;    /* shift u 1 bit to the left */
          if(digital(x))
    	u |= 1;   /* OR u with 0001 */
        }
        printf("ultra=%d  u=%d\n",ultra,u); 
        if (u != ultra)
          ultra=u;
      }
    }
    
    /*****************************************************
     *********         Move robot           **************
     *****************************************************/
    void move(int direction, int speed, long duration)
    {
      int sp1,sp2;
      long dur;
      
      move_status=running;
      if(direction==forward||direction==reverse)
      {
        sp1=direction*speed;
        sp2=sp1;
      }
      else if(direction==right)
      {
          sp1=reverse*speed;
          sp2=speed;
      }
      else if(direction==left)
      {
          sp1=speed;
          sp2=reverse*speed;
      }
      robot_status=moving;
      motor(0,sp1);
      motor(1,sp2);
      motor(2,sp2);
      motor(3,sp1);
      if (duration!=forever)
      {
        dur=mseconds();
        while(duration >=  mseconds()-dur);
        ao();
        robot_status=not_moving;
      }
      move_status=not_running;
      kill_process(move_pid);
    }
    
    
    
    /*****************************************************
     ************  Edge Evasive Maneuver   ***************
     *****************************************************/
    void edge_evade()
    {
      int dir,temp;
      
      edge_evade_status=running;
      temp=temp_edge;
    
      /**********     move away from edge     ***********/
      /* front edge detectors  dir=reverse */
      /* rear edge detectors   dir=forward */                      
      if (temp==1||temp==2||temp==3) 
        dir=reverse;
      else if (temp==4||temp==8||temp==12) 
        dir=forward;
      edge_evade_stage1=running;
      robot_status=moving;
      move_pid=start_process(move(dir,fast,forever));
      while (robot_status==moving);
    
      edge_evade_stage1=not_running;
    
      /****** turns towards the centre of platform  ******/
      if (temp==2||temp==8)
        dir=left;
      else if(temp==1||temp==4)
        dir=right;
      msleep(300l);
      move_status=running;
      move_pid=start_process(move(dir,medium,1500l));
      while (move_status==running);
    
      /******* move towards centre of platform  **********/
      move_status=running;
      move_pid=start_process(move(forward,slow,750l));
      while(move_status==running);
      
      edge_evade_status=not_running;
      kill_process(edge_evade_pid);
    }
    
    /*****************************************************
     **********  Contact Evasive Maneuver   **************
     *****************************************************/
    void contact_evade()
    {
      int c_dir;
      
      contact_evade_status=running;
    
      /* left contact  c_dir=right speed=fast_pivot duration=500l */
      /* right contact c_dir=left speed=fast_pivot duration=500l */
      /* front contact  c_dir=forward speed=fast duration=forever */
      /* rear contact   c_dir=reverse speed=fast duration=forever */                      
      if (temp_contact==1)  /* right contact */
        c_dir=left;
      else if (temp_contact==2)  /* left contact */ 
        c_dir=right;
      robot_status=moving;
      move_status=running;
      if (temp_contact <= 2 && temp_contact !=0)
        move_pid=start_process(move(c_dir,fast,forever));
    
      while(contact==temp_contact);
      
      contact_evade_status=not_running;
      kill_process(contact_evade_pid);
    }
    
    /*****************************************************
     ************    Obsticle Tracking     ***************
     *****************************************************/
    
    void tracking()
    {
     tracking_status=running;
    
     if(temp_ultra==1)
       move_pid=start_process(move(right,slow,forever));
     if(temp_ultra==2||temp_ultra==3||temp_ultra==4||temp_ultra==6||temp_ultra==12)
       move_pid=start_process(move(forward,slow,forever));
     if(temp_ultra==8)
       move_pid=start_process(move(left,slow_pivot,forever));
    
     tracking_status=not_running;
     kill_process(tracking_pid);
    }
    
    
    /*****************************************************
     *****************************************************
     *****************************************************
     *****************************************************
     *****************************************************
     ************        Main Program      ***************
     ***************************************************** 
     *****************************************************
     *****************************************************
     *****************************************************
     *****************************************************
     *****************************************************/
    void main() 
    { 
      int e,m,k,x,y,z;
      ao(); /* make sure that all motors and relays are off */
      k=1;
      /*  Initalize edge sensor values  */
      for(x=first_edge; x<=last_edge; x++)
      {
        z=0;
        for(y=0; y<=10; y++)
          z=z+analog(x);
        z=z/10;
        suface_value=suface_value+z;
        k++;
      }
      suface_value=suface_value/k;
      white_value=suface_value-20;
      if (suface_value+5 > 253)
        off_edge_value=253;
      else
        off_edge_value=suface_value+5;
      edge_pid=start_process(check_edge());
      contact_pid=start_process(check_contact());
      ultra_pid=start_process(check_ultra());
      /*  Main loop  */
      while (1) 
      { 
        if(edge!=temp_edge)
        {
          if(edge!=0)
          {
    	if(edge_evade_status==running)
    	{  
    	  kill_process(edge_evade_pid); 
    	  edge_evade_status=not_running;
    	}
    	if(contact_evade_status==running)
    	{
    	  kill_process(contact_evade_pid);
    	  contact_evade_status==not_running;
    	}
    	if(tracking_status==running)
    	{
    	  kill_process(tracking_pid);
    	  tracking_status=not_running;
    	}
    	if(move_status==running)
    	{
    	  kill_process(move_pid);
    	  move_status=not_running;
    	}
    	ao();
    	robot_status=not_moving;
    	temp_edge=edge;
    	edge_evade_pid=start_process(edge_evade());
          }
          else 
          {
    	if(edge_evade_stage1==running&&robot_status==moving)
    	{
    	  ao();
    	  robot_status=not_moving;
    	  if (move_status==running)
    	    kill_process(move_pid);
    	}
    	temp_edge=edge;
          } 
        }
        else if(contact!=temp_contact&&edge_evade_status==not_running)
        {
          if(contact!=0)
          {
    	if(tracking_status==running)
    	{
    	  kill_process(tracking_pid);
    	  tracking_status=not_running;
    	}
    	if(move_status==running)
    	{
    	  kill_process(move_pid);
    	  move_status=not_running;
    	}
    	ao();
    	robot_status=not_moving;
    	temp_contact=contact;
    	contact_evade_pid=start_process(contact_evade());
          }
          else if(contact_evade_status==running || robot_status==moving)
          {
    	if (contact_evade_status==running)
    	{
    	  kill_process(contact_evade_pid);
    	  contact_evade_status=not_running;
    	}
    	ao();
    	robot_status=not_moving;
    	temp_contact=contact;
          }
        }
        else if(ultra!=temp_ultra && edge_evade_status==not_running && 
    	    contact_evade_status==not_running)
        {
          if(ultra!=0)
          {
    	if(tracking_status==running)
    	{
    	  kill_process(tracking_pid);
    	  tracking_status=not_running;
    	}
    	if(move_status==running)
    	{  
    	  kill_process(move_pid);
    	  move_status=not_running;
    	}
    	if(robot_status==moving)
    	{
    	  ao();
    	  robot_status=not_moving;
    	}
    	temp_ultra=ultra;
    	tracking_pid=start_process(tracking());
          }
          else
          {
    	if(tracking_status==running)
    	  kill_process(tracking_pid);
    	if(move_status==running)
    	  kill_process(move_pid);
    	ao();
    	robot_status=not_moving;
    	temp_ultra=ultra;
          }
        }
      }
    }
    
    

    Next section
    
    Back to Dave's SUMO robot project page
    Back to Dave's home page
    Dave Chu Concordia University Electrical and Computer Engineering 1455 De Maisonneuve O. H941 Montreal, Quebec, Canada H3G 1M8 Telephone: (514) 848-3115 Fax: (514) 848-2802 Email: dave@ece.de-spam.concordia.ca