/* lib_nav.c created from lib_rw11.c for DocNav project 11/25/99 by GL
/*
VERSION HISTORY FOR lib_rw11.c
V2.81Jun 11 1994jlj
Created library for Rug Warrior from an earlier
library by jsr and fgm
*/
int abs(int arg)
{if (arg<0)
return -arg;
else
return arg;}
/*******************/
/* TIME PRIMITIVES */
/*******************/
/***********************************/
/* location of various time stuff: */
/* 0x14: time in milliseconds */
/***********************************/
void reset_system_time()
{
pokeword(0x14, 0);
pokeword(0x12, 0);
}
/* returns valid time from 0 to 32,767 minutes (approx) */
float seconds()
{
return ((float) mseconds()) / 1000.;
}
void sleep(float seconds)
{
msleep((long)(seconds * 1000.));
}
void msleep(long msec)
{
long end_time= mseconds() + msec;
while (1) {
/* if the following test doesn't execute at least once a second,
msleep may not halt */
long done= mseconds()-end_time;
if (done >= 0L && done <= 1000L) break;
}
}
long timer_create_seconds(float timeout)
{
return mseconds() + (long) (timeout * 1000.);
}
int timer_done(long timer)
{
return timer < mseconds();
}
int analog(int port)
{ poke(0x1039, 0b10000000);
poke(0x1030, port);
return peek(0x1031);
}
/*****************************/
/*** Multi-Tasking Support ***/
/*****************************/
/* gives process that calls it 256 ticks (over 1/4 sec)
more to run before being swapped out
call repeatedly to hog processor indefinitely */
void hog_processor()
{
poke(0x0a, 0);
}
int input_f(int port)/* Return 1 bit from portf PF1 or PF2 (or PF0) */
{ return 1 & (peek(0x7400) >> (port & 3));
}
int digital(int port) /* Return 1 bit from PA1 or PA2 (or PA0) */
{ return 1 & (peek(0x1000) >> (port & 3));
}
int round(float arg) /* thanks to George Musser for this one */
{int integer;
integer = (int)arg;
arg -= (float)integer;
if(arg >= 0.5)
return integer+1;
else if(arg <= -0.5)
return integer-1;
return integer;}
/***********************************************************/
/*
/* Motor Control Primitives
/*
/* init_motors()- Must be called to enable motors
/* motor(index, speed)- Control velocity of motor 0 (left) or 1 (right)
/* drive(trans_vel, rot_vel)- Control robot translation and rotation
/* stop()- Stop both motors
/* note motor control revised to match Rug Warrior Pro version (int velocity)
/* Setup two PWM channels for motor control */
/* Left Right */
int TOCx[2] = {0x1018, 0x101A};/* Index for timer register */
int dir_mask[2] = {0b00010000, 0b00100000};/* Port D direction bits */
int pwm_mask[2] = {0b01000000, 0b00100000};/* Port A PWM bits */
int init_motors()
{ bit_set(0x1009,0b110000);/* Set PD4,5 as outputs for motor direction */
poke(0x100C,0b01100000);/* OC1M Output compare 1 affects PA5,6 */
bit_set( 0x1020,0b10100000);/* TCTL1 OC3 turns off PA5, OC2 PA6 */
bit_clear(0x1020,0b01010000);/* Use set and clear to avoid other bits */
pokeword(0x1016,0);/* When TCNT = 0, OC1 fires */
}
/* Make sure init_motors is called after a reset */
int init_motors_dummy = init_motors();
void stop()/* Stop both drive motors */
{ bit_clear(0x100D,pwm_mask[0]);/* Let OC1 turn off motors rather */
bit_clear(0x100D,pwm_mask[1]);/* than turn them on */
}
/* Vel is in the range [-100, +100], index = 0 => Left, = 1 => Right */
void motor(int index, int vel)
{ int avel = vel;
if (vel == 0) /* Check first for zero vel */
{ bit_clear(0x100D,pwm_mask[index]); /* OC1 turns off the motor */
return; } /* And, you're done */
bit_set(0x100D,pwm_mask[index]); /* Otherwise let OC1 control the motors */
if (vel > 0)
{ bit_set(0x1008, dir_mask[index]);} /* Forward rotation */
else
{ avel = (- vel);
bit_clear(0x1008, dir_mask[index]);} /* Backward rotation */
if (avel > 99)
pokeword(TOCx[index], 0); /* 0 means OC1 wins, motor on */
else
pokeword(TOCx[index], (655 * avel)); /* Compute TOCx value */
}
/* Use drive to control motion of the robot. A positive rot_vel makes the robot
turn left. */
void drive(int trans_vel, int rot_vel)
{ motor(0,trans_vel - rot_vel);
motor(1,trans_vel + rot_vel);
}
/* WARNING: printf's will wedge once the print buffer becomes full
if system printing is disabled */
void system_print_on() {bit_set(0x39, 0b00000001);}
void system_print_off() {bit_clear(0x39, 0b00000001);}
/********************** END *******************/