Robot Client

 

The robot client is defined in the robotclient.c file.  It contains all the necessary code for the Handyboard to work with the robot server program.  First, let’s look at all the important defines used by the robot client.

 

The Defines

 

The following defines contain information needed by the code that might need to be changed.  These are used in place of global variables in the interest of saving space.

 

#ifndef bool

#define bool int

#define true 1

#define false 0

#endif

 

#define DELAY 0l

#define TIMEOUT 500l

#define DELAY_PER_DEGREE 0.005556

 

#define GEAR_RATIO 25

#define TICKS_PER_REVOLUTION 12*GEAR_RATIO

#define WHEEL_DIAMETER 2.5625

#define WHEEL_CIRCUMFRANCE 8.050331

#define INCHES_PER_TICK 0.026834

#define DEGREES_PER_TICK 0.984

#define WHEEL_BASE 3.125

 

/* MACROS */

#define disable_pcode_serial() poke(0x3c, 1)

#define enable_pcode_serial() poke(0x3c, 0)

 

#define LEFT_ENCODER_PORT             0

#define RIGHT_ENCODER_PORT            1

#define BREAK_BEAM_SENSOR_PORT        2

#define LIGHT_SENSOR_PORT             3

#define LEFT_FRONT_BUMP_SENSOR_PORT  14

#define RIGHT_FRONT_BUMP_SENSOR_PORT 15

 

#define LEFT_MOTOR_PORT 0

#define RIGHT_MOTOR_PORT 1

 

#define THIS_ROBOT_ID 42

#define ANY_ROBOT_ID 0

 

#define SENSOR_LAYOUT_SIZE 10

 

#define INFO_SIZE 10

#define SONAR_DATA_SIZE  61

#define SONAR_DPI 8

#define SONAR_DATA_START_INDEX  4

#define SONAR_DATA_END_INDEX   64

#define NAME "Johnny 5"

 

#define SENSOR_DATA_SIZE 65

Booleans are defined as integers.

 

 

 

 

 

Delay(ms) between sending characters*

Delay(ms) before packets are resent*

Constant used during turning

 

These relate to the physical size of the gear train and wheels on the robot.  They are used when moving or turning the robot.

 

 

 

 

 

Allows serial_getchar to work*

Allows IC to interact with Handyboard*

 

These define the port numbers for the various sensors.  Each robot will be different.

 

 

 

 

These define the left and right motor ports for the robot.

 

Make sure no other robot has this ID*

Used to refer to all robots*

 

This is 2 * (# of sensors)*

 

Length of NAME + (# of other info)*

(# of angles sonar reads) + 1*

Resolution of sonar in divisions/inch*

Starting index of sonar data in array

Ending index of sonar data in array

Name of robot*

 

Length of sensor data array*

 

* These defines contain necessary information for the server and for communications.


 The defines listed above are not all the defines used by the robot client.  See the defines.c file for a complete list of (not necessarily implemented) opcodes, movement directions, sensor types, and locations.  This file can be changed as more of these types are implemented.  The important thing is to make sure that it corresponds with the Defines.java file and to define a _END for each type (See defines.c).  This is used when iterating through the types.  See the packet.c file for defines relating to the packet format.  MAX_DATA_SIZE can be adjusted as necessary but should be kept small.

 

The Global variables

 

Besides all the defines that are needed, there are a few data structures and other global variables used by the robot client.  The data structures are mainly used to define the physical structure of the robot (which may be different for each one) and to make it easier for client/server communications.

 

Defined in the robotclient.c file:

 

char sensor_layout[SENSOR_LAYOUT_SIZE]=

{BUMP_SENSOR, LEFT_FRONT,

 BUMP_SENSOR, RIGHT_FRONT,

 BREAK_BEAM_SENSOR, FRONT,

 LIGHT_SENSOR, FRONT,

 SONAR_SENSOR, TOP_FRONT};

 

char sensor_data[SENSOR_DATA_SIZE];

The sensor layout array.  This is important for the server to properly parse data packets.  The array alternates sensor type and sensor location (See defines.c)

 

 

 

The sensor data array

 

Defined in the packet.c file:

 

char packet_buffer[MAX_PACKET_SIZE];

The packet buffer.

 

The various other global variables are used for robot operation.  They include Boolean flags and variables used for movement commands:

 

Bool registered;

bool sense_enabled;

bool auto_scan;

bool manual_scan_once;

bool sonar_data_ready;

 

char movement_direction;

char movement_distance;

int left_motor_direction,

    right_motor_direction;

Flag set true when robot added to server

Flag set true when sensing is enabled

Flag set true if auto scanning is enabled

Flag set true each time manual scan needed

Flag set true when sonar completes a sweep

 

These movement variables are set when a movement command is sent (See defines.c)

These are either 1 or –1 for forward and backward respectively

 

 


The Program Structure

 

Now that the important information is set up, Let’s look at the overall structure of the code.  First is the main function:

 

void main(void){

  int pid[4];

 

  init();

  printf("I am %s!\n", NAME);

 

  pid[0]=start_process(sense());

  pid[1]=start_process(communicate());

  pid[2]=start_process(sonar_scan());

  pid[3]=start_process(move());

 

  while(!stop_button()){

    defer();

  }

 

  kill_process(pid[0]);

  kill_process(pid[1]);

  kill_process(pid[2]);

  kill_process(pid[3]);

  close();

}

 

The main function sets up the various processes that will be used.  The order is not necessarily since these processes are run (virtually) in parallel. Both sense and sonar_scan are used to fill the sensor_data array, communicate handles all the communications between the client and server, and move just handles forward/backward movement and turning of the robot.

 

Move

 

The move process has been provided for basic functionality.  It can be changed as needed, but it will need to use the global movement variables (see above) in order to determine direction and distance.

 

Sense

 

The sense process fills in the first part of the sensor_data array with non-sonar sensor data (in the order that they are defined in the sensor_layout).  This will have to be adjusted for each robot, since the sensor layout will be different.

 

Sonar Scan

 

The sonar_scan process controls the sonar scanning and fills in the last part of the sensor_data array with sonar sensor data.  This process shouldn’t have to be changed since it relies on defines and global flags for variable functionality.

 

Communicate

 

The most important process is the communicate process.  It handles all the communications between the robot and the server.  The actual process is rather simple:

 

void communicate() {

  while(1) {

    while(!receivePacket())

      defer();

    sendResponse();

  }

}

 

This process waits until a packet is received, handles any commands, and then sends an appropriate response.

 

 

Updating the Robot Client

 

The communications protocol allows for error checking but it is not currently implemented.  To add error checking, modify the receivePacket and sendPacket functions in robotclient.c.  Error checking functionality will have to be added to the server as well.  Currently, rdt (reliable data transfer) version 2.0 (assuming no errors) is implemented.  However, it could easily be extended to rdt version 3.0 with a checksum or even a CRC.

 

The sendResponse function handles all the implemented opcodes and sends the appropriate response for each one.  This is the function to modify if additional opcodes are added.