218B Software Specification
218B Software Specification
CycleShootHSM
Events
ES_TIMEOUT
States
CycleShootEntry
CycleShootTension
CycleShootFire
CycleShootRelease
CycleShootSecure
Conventions
Events
All events should be in UPPER_CASE_SNAKE_CASE and be clear which service they apply to.
Ideally, the service name (or part of it) should be included in the event name unless event
meaning is unambiguous without it.
Framework events (ES_ENTRY, ES_NEW_KEY, etc) should be used as written in the template
and no other events should begin with ES
Examples:
DRIVE_MOVE_FORWARD - DRIVE is short for drive train
START_BUTTON_PRESSED - No service name, but it is clear that this event occurs when the
physical start button is pressed
CYCLE_COMPLETE - CYCLE refers to CYCLE state machine
States
States should be in CamelCase and unique to their service, preferably including the service
name (or part of it) and the word State, especially if there are similarly named events. There
cannot be multiple enums with the same state name or there will be an error (Do not use
InitPState. Rename it).
Example:
RobotInitState - State in RobotTopHSM
Events
ROBOT_INIT_COMPLETE
Event to trigger transition to RobotInactiveState after hardware initialization complete
START_BUTTON_PRESSED
Posted by Start Button Event Checker when it is pressed
ES_TIMEOUT
Timeouts occur 1) when the start button is pressed to allow the user to move their finger out of
the way before movement starts and 2) to allow the servos to move back to initial positions in a
sequence after a game has ended (since the game might end in the middle of a shooting cycle
and we need to move these servos in a particular order)
GAME_TIMEOUT
This game timeout occurs after 2 minutes 18 seconds have elapsed in a game
States
RobotInitState
Services and Hardware are in the process of being reset to their initial status:
Initialize all hardware
Untension spring and
reset reloader (hold state) and
lower game status flag
Start 1 second timer (just to
give the user enough time to
get out of the way)
RobotInactiveState
Initialization complete. All lower level state machines suspended and nothing is moving
RobotActiveState
Main state for when robot is in an active game
Events
GAME_STARTUP_COMPLETE
Posted when all startup motions are finished and cycling is ready to begin
GAME_CYCLE_COMPLETE
Robot returned to reload zone and ready to be refilled
REFILL_BUTTON_PRESSED
Refill button pressed. Tells robot to begin new cycle
START_BUTTON_PRESSED
Start button pressed. Tells robot to begin new rehoming cycle
REHOME_DONE
Rehoming cycle is done and we return back to the GameRefillState
States
GameStartupState
Robot is performing initial find beacon and motion to move to cycling position
GameCycleState
Robot is in a shooting cycle
GameRefillState
Robot is idle in reload zone waiting for human to load balls and press reload button
GameRehomeState
Run RehomeHSM
Events
GAME_STARTUP_COMPLETE
Posted when all startup motions are finished and cycling is ready to begin
STARTUP_STEP_COMPLETE
Tells robot to move to next step of startup sequence
MOTORS_STOPPED
Tells robot to move to next step of startup sequence
DRIVE_GOAL_REACHED
Tells robot to move to next step of startup sequence
BUMP_OCCURRED
Tells robot to move to next step of startup sequence
States
StartupInitState
Enable Game Status indicator and start 2:18 timer
FindBeaconState
Robot rotating until it sees beacon
DetermineTeamState
Robot measuring beacon frequency and setting team indicator
RotateToSideState
Robot performing 1st CCW rotation to move to 5pt starting position
DriveToWallState
Robot driving straight until it reaches side wall to move to 5pt starting position
MoveFromWallState
Robot moving forward slightly (3 cm) to prevent wall collision while upcoming rotation
RotateToForwardState
Robot performing 2nd CW rotation to face the 5pt starting position
CycleShootHSM
HSM that handles ordering and control of servo commands to perform a shot
Events
ES_TIMEOUT
This is a timeout for each step. The steps must be executed sequentially so this allows for the
state machine to progress without implementing blocking code
States
CycleShootEntry
This is the entry state. We just ensure the latch servo is closed here so that tensioning will be
successful
CycleShootTension
Tension the springs
CycleShootFire
Open the latch to fire
CycleShootRelease
Release tension on the springs to allow the catapult arm to fall back into resting position
CycleShootSecure
Close the latch servo to secure the catapult arm
Events
ES_TIMEOUT
After the start button is pressed to initiate a rehoming procedure, a one second timer is set to
allow the user to move their finger out of the way before the bot starts moving. This is the
timeout event for that one second timer, allowing the state machine to progress.
DRIVE_GOAL_REACHED
This event gets posted when the bot is finished rotating a certain amount (in this case, 90
degrees)
BUMP_OCCURRED
This event gets posted when the bot, after having driven backwards, either hits the wall with its
bumper sensor (limit switch) or a 4 second timeout has occurred (just in case it hits the wall off
center and would otherwise get stuck).
States
RehomeInitState
Waiting for 1 second timeout to occur before movement starts
RehomeRotateToSideState
Rotating 90 degrees clockwise
RehomeDriveToWallState
Drive backwards until the bump sensor (or timeout) is activated (a bump occurs)
RehomeMoveFromWallState
Move forward 3 cm to prevent touching the wall while rotating
RehomeRotateToForwardState
Rotate 90 degrees counterclockwise to face the front again
Events
BEACON_FOUND
Posted when the BeaconSM has detected the beacon
RELOAD_COMPLETE
Posted when reloading is complete
SHOOT_COMPLETE
Posted when a shot is completed
DRIVE_GOAL_REACHED
Posted when 1) the 45 cm forward distance has been traversed when the bot is initially moving
forward into the 5 point scoring region, 2) if the beacon was not found after a full 360 degree
sweep, and 3) when undoing an alignment rotation is completed after shooting
ES_TIMEOUT
This timeout corresponds to a short delay between detecting the beacon and telling the motors
to stop. This allows us to aim closer to the center of the goal instead of at the edge
BEACON_ACKNOWLEDGED
This event is an acknowledgement from the Drive PIC that it has stored the rotation amount
corresponding to the beacon location. After shooting is completed, it will anticipate undoing this
rotation to return to a forward facing position so that we can back up into the reload zone again
BUMP_OCCURRED
This event occurs when the bumper sensor (limit switch) is triggered, which occurs when we
drive backwards to return to the reload zone
MOTORS_STOPPED
This is an acknowledgement from the Drive PIC that the motors have stopped, which occurs
after the bot has reached the back wall (and hence is in the reload zone)
States
CycleDriveForwardState
Robot driving forward until it is fully in 5pt zone
CycleAimState
Robot rotating until it sees beacon to fine tune aiming
CycleReloadState
Loading ball:
Reload Servo Forward (start timer)
(upon timeout) Reload Servo Backward
CycleShootState
Run CycleShootHSM
CycleUndoRotationState
Send undo rotation command to Drive PIC
CycleDriveBackState
Robot reversing until it enters reload zone
CycleStoppingState
Send stop command to Drive PIC; change event to GAME_CYCLE_COMPLETE when stop is
acknowledged
Events
GIVE_UP
Tells the Find_Beacon state machine to give up (this would allow an external state machine or
service to force it to stop even if it hasn’t detected a beacon yet, but ended up being unused)
BEACON_FOUND
Posted by the input capture interrupt service routine in the event that the beacon was found
FIND_BEACON
Posted by an external state machine or service to initiate searching for the beacon
States
BeaconWaitingState
Doing nothing
BeaconSearchingState
Actively searching for the beacon (interrupts are enabled, input capture is on)
Pseudocode
/****************************************************************************
Function
InitFind_Beacon
Parameters
uint8_t : the priorty of this service
Returns
bool, false if error in initialization, true otherwise
Description
Saves away the priority, sets up the initial transition and does any
other required initialization for this state machine
Notes
Author
Ryan Brandt
****************************************************************************/
Do lots of setup:
Setup the timer 2 for input capture 1: SetupTimer2()
return true
/****************************************************************************
Function
PostFind_Beacon
Parameters
EF_Event_t ThisEvent , the event to post to the queue
Returns
boolean False if the Enqueue operation failed, True otherwise
Description
Posts an event to this state machine's queue
Notes
Author
J. Edward Carryer, 10/23/11, 19:25
****************************************************************************/
/****************************************************************************
Function
RunFind_Beacon
Parameters
ES_Event_t : the event to process
Returns
ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise
Description
Implements the state machine for finding the beacon
Notes
uses nested switch/case to implement the machine.
Author
Ryan Brandt
****************************************************************************/
if TeamIdentity is Red
Output “Searching for Team Red's Beacon” to terminal
else if TeamIdentity is Blue
Output “Searching for Team Blue's Beacon” to terminal
else
Output “Cannot search yet - need to determine team identity first” to terminal
break
/****************************************************************************
Function
QueryFind_Beacon
Parameters
None
Returns
Find_BeaconState_t The current state of the Template state machine
Description
returns the current state of the Template state machine
Notes
Author
J. Edward Carryer, 10/23/11, 19:21
****************************************************************************/
Find_BeaconState_t QueryFind_Beacon(void)
return CurrentState
/****************************************************************************
Function
QueryTeamIdentity
Parameters
None
Returns
TeamIdentity_t TeamIdentity
Description
returns the current team identity
Notes
Author
Ryan Brandt
****************************************************************************/
TeamIdentity_t QueryTeamIdentity(void)
return TeamIdentity
If Timer 2?s rollover interrupt is active (IFS0bits.T2IF is 1) and the CapturedTime is after
rollover (<0x8000):
Increment RolloverCounter
Clear the rollover interrupt (IFS0CLR = _IFS0_T2IF_MASK)
Set CapturedTime += (RolloverCounter << 16) (aka lower 16 bits are from the buffer
and upper 16 bits are from the rollover buffer)
If FirstMeasurementFlag is true, this is the first measurement, so collect it, disable the
flag, and get out:
Save CapturedTime into LastRiseTime
Disable the flag (set FirstMeasurementFlag to false)
Else, this is not the first measurement, so we can measure a pulse period and report a
duration:
Calculate the last pulsePeriod as CapturedTime - LastRiseTime (pulsePeriod is a
volatile uint32_t module level variable)
if SearchMode is DetermineTeam
If pulsePeriod is in an acceptable range for the red team; aka:
if (((pulsePeriod < REDTEAM_PULSEMAX) && (pulsePeriod >
REDTEAM_PULSEMIN)) && (!Found))
DisableIC4Interrupts()
return true
Events
FLAG_UP
Sets the game indicator flag to the up position
FLAG_DOWN
Sets the game indicator flag to the down position
RELOAD_OUT
Sets the reloader to the out position
RELOAD_IN
Sets the reloader to the in position
LATCH_ENGAGE
Sets the catapult latch to the engaged position
LATCH_RELEASE
Sets the catapult latch to the released position
TENSION_ENGAGE
Sets the catapult tensioner to the engaged position
TENSION_RELEASE
Sets the catapult tensioner to the released position
SERVO_RESET
Resets servo positions
Pseudocode
/****************************************************************************
Function
InitLaunchService
Parameters
uint8_t : the priorty of this service
Returns
bool, false if error in initialization, true otherwise
Description
Saves away the priority, sets up the initial transition and does any
other required initialization for this state machine
Notes
Author
Afshan Chandani
****************************************************************************/
/****************************************************************************
Function
PostLaunchService
Parameters
ES_Event_t ThisEvent , the event to post to the queue
Returns
boolean False if the Enqueue operation failed, True otherwise
Description
Posts an event to this state machine's queue
Notes
Author
Afshan Chandani
****************************************************************************/
/****************************************************************************
Function
RunLaunchService
Parameters
ES_Event_t : the event to process
Returns
ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise
Description
Notes
uses nested switch/case to implement the machine.
Author
Afshan Chandani
****************************************************************************/
Switch on Event
In case of each event, set the corresponding output compare module to the duty cycle in the
define section
OC1 - Reloader
OC3 - Tensioner
OC4 - Flag
OC5 - Latch
START_BUTTON_CHANGE
The start button has changed states
States
StartButtonHigh
The button is in a high state
StartButtonLow
The button is in a low state
Pseudocode
/****************************************************************************
Function
InitStartButton
Parameters
uint8_t : the priorty of this service
Returns
bool, false if error in initialization, true otherwise
Description
Saves away the priority, sets up the initial transition and does any
other required initialization for this state machine
Notes
Author
Afshan Chandani
****************************************************************************/
/****************************************************************************
Function
PostStartButton
Parameters
ES_Event_t ThisEvent , the event to post to the queue
Returns
boolean False if the Enqueue operation failed, True otherwise
Description
Posts an event to this state machine's queue
Notes
Author
Afshan Chandani
****************************************************************************/
/****************************************************************************
Function
RunStartButton
Parameters
ES_Event_t : the event to process
Returns
ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise
Description
Notes
uses nested switch/case to implement the machine.
Author
Afshan Chandani
****************************************************************************/
ES_Event_t RunStartButton(ES_Event_t ThisEvent)
Switch on CurrentState
case StartButtonHigh:
if EventType is START_BUTTON_CHANGE
Start StartButtonTimer
if EventType is ES_TIMEOUT - debounce is satisfied
if CurrentButtonState is low
CurrentState = StartButtonLow
Post START_BUTTON_PRESSED to Top HSM
case StartButtonLow:
if EventType is START_BUTTON_CHANGE
Start StartButtonTimer
if EventType is ES_TIMEOUT
if CurrentButtonState is high
CurrentState = StartButtonHigh
/****************************************************************************
Function
CheckStartButtonEvents
Parameters
None
Returns
True if start button has changed states
Description
Check if the start button has changed states
Notes
Author
Afshan Chandani
****************************************************************************/
bool CheckStartButtonEvents(void)
Events
RELOAD_BUTTON_CHANGE
The Reload button has changed states
States
ReloadButtonHigh
The button is in a high state
ReloadButtonLow
The button is in a low state
Pseudocode
/****************************************************************************
Function
InitReloadButton
Parameters
uint8_t : the priorty of this service
Returns
bool, false if error in initialization, true otherwise
Description
Saves away the priority, sets up the initial transition and does any
other required initialization for this state machine
Notes
Author
Afshan Chandani
****************************************************************************/
bool InitReloadButton(uint8_t Priority)
/****************************************************************************
Function
PostReloadButton
Parameters
ES_Event_t ThisEvent , the event to post to the queue
Returns
boolean False if the Enqueue operation failed, True otherwise
Description
Posts an event to this state machine's queue
Notes
Author
Afshan Chandani
****************************************************************************/
/****************************************************************************
Function
RunReloadButton
Parameters
ES_Event_t : the event to process
Returns
ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise
Description
Notes
uses nested switch/case to implement the machine.
Author
Afshan Chandani
****************************************************************************/
Switch on CurrentState
case ReloadButtonHigh:
if EventType is RELOAD_BUTTON_CHANGE
Reload ReloadButtonTimer
if EventType is ES_TIMEOUT - debounce is satisfied
if CurrentButtonState is low
CurrentState = ReloadButtonLow
Post Reload_BUTTON_PRESSED to Top HSM
case ReloadButtonLow:
if EventType is RELOAD_BUTTON_CHANGE
Reload ReloadButtonTimer
if EventType is ES_TIMEOUT
if CurrentButtonState is high
CurrentState = ReloadButtonHigh
/****************************************************************************
Function
CheckReloadButtonEvents
Parameters
None
Returns
True if Reload button has changed states
Description
Check if the Reload button has changed states
Notes
Author
Afshan Chandani
****************************************************************************/
bool CheckReloadButtonEvents(void)
Events
SEND_SPI_COMMAND
Posted by other services to SPI Leader with a 16 bit param of what drive code to send to PIC2
SPI_RESPONSE_RECEIVED
Posted by SPI Event Checker to the SPI Leader to indicate that PIC2 has sent back data
SPI_TASK_COMPLETE
Posted by SPI Leader to HSM to indicate the current drive task has completed execution
SPI_TASK_FAILED
Posted by SPI Leader to HSM to indicate the current drive task has failed execution
SPI_RESET
Resets SPI Leader
Events
SPI_COMMAND_RECEIVED
Posted by SPI Event Checker to the SPI Follower to indicate that PIC1 has sent data
SPI_TASK_COMPLETE
Posted by SM to SPI Follower to indicate the current drive task has completed execution
SPI_TASK_FAILED
Posted by SM to SPI Follower to indicate the current drive task has failed execution
SPI_RESET
Resets SPI Follower
States
SPIFollowerInitState
SPI is initialized
SPIFollowerReceiveState
SPI Follower waits for a command to be passed into it from PIC1, and then posts the correct
event to the SM
Pseudocode
/****************************************************************************
Function
InitSPIFollowerSM
Parameters
uint8_t : the priorty of this service
Returns
bool, false if error in initialization, true otherwise
Description
Saves away the priority, sets up the initial transition and does any
other required initialization for this state machine
Notes
Author
Andrew Sack
****************************************************************************/
Parameters
ES_Event_t ThisEvent , the event to post to the queue
Returns
boolean False if the Enqueue operation failed, True otherwise
Description
Posts an event to this state machine's queue
Notes
Author
Andrew Sack
****************************************************************************/
/****************************************************************************
Function
RunSPIFollowerSM
Parameters
ES_Event_t : the event to process
Returns
ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise
Description
Notes
uses nested switch/case to implement the machine.
Author
Andrew Sack
****************************************************************************/
ES_Event_t RunSPIFollowerSM(ES_Event_t ThisEvent)
Switch on CurrentState
case SPIFollowerInitState:
if EventType is ES_INIT
Call InitializeSPI
If it returns true
Set CurrentState to SPIFollowerReceiveState
Else return ES_ERROR
case SPIFollowerReceiveState:
If EventType is SPI_COMMAND_RECEIVED
call DecodeSPICommand() for the event
/****************************************************************************
Function
QuerySPIFollowerSM
Parameters
None
Returns
SPIFollowerSMState_t The current state of the SPIFollowerSM state machine
Description
returns the current state of the Drive Train state machine
Notes
Author
Andrew Sack
****************************************************************************/
SPIFollowerSMState_t QuerySPIFollowerSM(void)
return CurrentState
/****************************************************************************
Function
InitializeSPI
Parameters
None
Returns
True if successful, else false
Description
Initializes SPI module as follower
Notes
Author
Andrew Sack
****************************************************************************/
bool InitializeSPI(void)
Set SSEN to 0
Set SPIROV to 0
/****************************************************************************
Function
CheckSPIRBF
Parameters
None
Returns
True if something read from buffer
Description
Check if something is in SPI buffer and if so, post an event
Notes
Author
Andrew Sack
****************************************************************************/
bool CheckSPIRBF(void)
/****************************************************************************
* Function
* DecodeSPICommand
*
* Parameters
* SPI_MOSI_Command_t SPICommand - Command struct to be decoded
* Return
* void
* Description
* Takes 16bit val cast to a struct, decodes it and posts correct event to
* Framework
****************************************************************************/
switch on SPICommand.Name
case SPI_POLL:
Do nothing
case SPI_STOP:
Post DRIVE_STOP event to DriveTrain and BumperService
case SPI_DRIVE_DISTANCE:
Post DRIVE_DISTANCE event to DriveTrain service
case SPI_DRIVE_UNTIL_BUMP:
Post DRIVE_UNITL_BUMP event to DriveTrain and BumperService
case SPI_DO_TAPE_ALIGN:
Post DRIVE_TAPE_ALIGN event to DriveTrain service
case SPI_DO_BEACON_SWEEP:
Post DRIVE_BEACON_SWEEP event to DriveTrain service
case SPI_BEACON_FOUND:
Post BEACON_FOUND event to DriveTrain service
case SPI_UNDO_ROTATE:
Post DRIVE_UNDO_ROTATE event to DriveTrain service
DRIVE_STOP
In any state, the DriveTrain will stop the motors and move to DriveStoppedState
DRIVE_DISTANCE
Do a drive of the specified type for specified distance
DRIVE_UNTIL_BUMP
Drive backward until BUMP_FOUND event received
DRIVE_BEACON_SWEEP
Start performing beacon sweep
DRIVE_UNDO_ROTATE
Rotate back to stored orientation
DRIVE_GOAL_REACHED
Posted by DriveTrain when a distance goal is reached
States
DriveInitState
Initializing hardware and registers
DriveStoppedState
Initialization complete. Robot is not moving
DriveDistanceState
Robot is moving for a specified distance or indefinitely
DriveUntilBumpState
Robot is driving straight backward and waiting for a BUMP_FOUND event
DriveClockwiseSweepState
Robot turning clockwise and waiting for either DRIVE_GOAL_REACHED or BEACON_FOUND
event
DriveOverRotateState
Robot continuing turning by set amount after seeing beacon and waiting for
DRIVE_GOAL_REACHED event
DriveBeaconWaitState
Robot not moving and waiting for DRIVE_UNDO_ROTATE event
DriveUndoRotateState
Robot rotating for specified distance back to original angle
Pseudocode
/****************************************************************************
Function
InitDriveTrain
Parameters
uint8_t : the priority of this service
Returns
bool, false if error in initialization, true otherwise
Description
Saves away the priority, sets up the initial transition and does any
other required initialization for this state machine
Notes
Author
Andrew Sack
****************************************************************************/
Parameters
ES_Event_t ThisEvent , the event to post to the queue
Returns
boolean False if the Enqueue operation failed, True otherwise
Description
Posts an event to this state machine's queue
Notes
Author
Andrew Sack
****************************************************************************/
/****************************************************************************
Function
RunDriveTrain
Parameters
ES_Event_t : the event to process
Returns
ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise
Description
Notes
uses nested switch/case to implement the machine.
Author
Andrew Sack
****************************************************************************/
ES_Event_t RunDriveTrain(ES_Event_t ThisEvent)
Switch on CurrentState
case DriveInitState:
If ES_INIT
Stop Motors
Set CurrentState to DriveStoppedState
case DriveStoppedState
Switch on ThisEvent.EventType
case DRIVE_DISTANCE:
if SPICommand.DriveType is Translation
call MotorControl_DriveStraight with params from SPICommand
else if SPICommand.DriveType is Rotation
call MotorControl_DriveTurn with params from SPICommand
Set CurrentState to DriveDistanceState
case DRIVE_UNTIL_BUMP:
call MotorControl_DriveStraight to drive backwards at medium speed indefinitely
Set CurrentState to DriveUntilBumpState
case DRIVE_BEACON_SWEEP:
call MotorControl_DriveTurn to turn CW by SWEEP_CW_ANGLE at low speed
Set CurrentState to DriveClockwiseSweepState
case DriveDistanceState:
If EventType is DRIVE_GOAL_REACHED
Stop Motors
Set CurrentState to DriveStoppedState
Post DRIVE_GOAL_REACHED to SPI
case DriveUntilBumpState:
If EventType is BUMP_FOUND
Stop Motors
Set CurrentState to DriveStoppedState
case DriveClockwiseSweepState:
If EventType is BEACON_FOUND
Save Current Left Encoder TickCount to SweepAmount
Call DriveTurn Clockwise at low speed by Overrotate amount
Set CurrentState to DriveOverRotateState
else if EventType is DRIVE_GOAL_REACHED
Stop Motors
Post DRIVE_GOAL_REACHED to SPI Service
Set CurrentState to DriveStoppedState
case DriveOverRotateState:
if EventType is DRIVE_GOAL_REACHED
Stop Motors
Post BEACON_ACKNOWLEDGED to SPI Service
Set CurrentState to DriveBeaconWaitState
case DriveBeaconWaitState:
if EventType is DRIVE_UNDO_ROTATE
if SweepAmount > 0 (clockwise)
Calculate Angle from SweepAmount
Undo Rotation by angle in ccw direction
else
Calculate Angle from SweepAmount
Undo Rotation by angle in cw direction
Set CurrentState to DriveUndoRotateState
case DriveUndoRotateState:
if EventType is DRIVE_GOAL_REACHED
Stop Motors
Post DRIVE_GOAL_REACHED to SPI Service
Set CurrentState to DriveStoppedState
/****************************************************************************
Function
QueryDriveTrain
Parameters
None
Returns
DriveTrainState_t The current state of the DriveTrain state machine
Description
returns the current state of the Drive Train state machine
Notes
Author
Andrew Sack
****************************************************************************/
DriveTrainState_t QueryDriveTrain(void)
return CurrentState
Pseudocode
// Initialization function for Driver. Configures all pins, timers, interrupts
bool InitMotorControlDriver(void);
/****************************************************************************
* Function
* MotorControl_SetMotorDutyCycle
*
* Parameters
* MotorControl_Motor_t WhichMotor - Left or Right Motor
* MotorControl_Direction_t WhichDirection - Direction to move motor in
* Forward is relative to robot base (CW for right motor, CCW for left)
* uint16_t DutyCycle - (valid range 0-1000 inclusive) PWM duty cycle to set
* Return
* void
* Description
* Set specified motor to move at set PWM duty cycle in specified direction
* Only works with CLosed Loop Control Disabled
****************************************************************************/
/****************************************************************************
* Function
* MotorControl_StopMotors
*
* Parameters
* void
* Return
* void
* Description
* Stop both motors, and cancel any tick goal
****************************************************************************/
void MotorControl_StopMotors(void);
Call SetMotorDutyCycle for both left and right motor with duty cycle of 0
Set Left and Right TargetRPM to 0
Set Left and Right TargetTickCount to 0
Clear all DriveGoal Active and Reached flags
/****************************************************************************
* Function
* MotorControl_EnableClosedLoop
*
* Parameters
* void
* Return
* void
* Description
* Enables Control Law timer interrupt, causing motors to follow CL control
* SetMotorDutyCycle will not work properly when enabled
****************************************************************************/
void MotorControl_EnableClosedLoop(void);
/****************************************************************************
* Function
* MotorControl_DisableClosedLoop
*
* Parameters
* void
* Return
* void
* Description
* Disables Control Law timer interrupt. Motors use direct Duty Cycle
* SetMotorDutyCycle will not work properly when enabled
****************************************************************************/
void MotorControl_DisableClosedLoop(void);
/****************************************************************************
* Function
* MotorControl_SetMotorSpeed
*
* Parameters
* MotorControl_Motor_t WhichMotor - Left or Right Motor
* MotorControl_Direction_t WhichDirection - Direction to move motor in
* Forward is relative to robot base (CW for right motor, CCW for left)
* uint16_t Speed - target speed to move at in units of 0.1 RPM (5 RPM = 50)
* Max speed is approx 170 RPM
* Return
* void
* Description
* Set specified motor to move at set PWM duty cycle in specified direction
* Only works when CloseLoop is enabled
****************************************************************************/
EnableClosedLoop()
/****************************************************************************
* Function
* MotorControl_ResetTickCount
*
* Parameters
* MotorControl_Motor_t WhichMotor - Left or Right Motor
* Return
* void
* Description
* Sets current tick count for specified motor to zero
****************************************************************************/
if motor is LeftMotor
Set Left TickCount to 0
else if motor is RightMotor
Set Right TickCount to 0
/****************************************************************************
* Function
* MotorControl_SetTickGoal
*
* Parameters
* MotorControl_Motor_t WhichMotor - Left or Right Motor
* uint32_t NumTicks - Amount of ticks encoder will count to before stopping
* Return
* void
* Description
* Sets tick goal for specified motor to NumTicks
****************************************************************************/
if motor is LeftMotor
Set Left TargetTickCount to NumTicks
Set Left DriveGoalReached to false
if NumTicks nonzero set LeftDriveGoalActive to true, else false
else if motor is RightMotor
Set Right TargetTickCount to NumTicks
Set Right DriveGoalReached to false
if NumTicks nonzero set RightDriveGoalActive to true, else false
/****************************************************************************
* Function
* MotorControl_GetEncoder
*
* Parameters
* MotorControl_Motor_t WhichMotor - Left or Right Motor
* Return
* Encoder_t struct for specified motor
* Description
* Get function to return Encoder Struct for specified Motor
****************************************************************************/
/****************************************************************************
* Function
* MotorControl_GetControlState
*
* Parameters
* MotorControl_Motor_t WhichMotor - Left or Right Motor
* Return
* ControlState_t struct for specified motor
* Description
* Get function to return ControlState Struct for specified Motor
****************************************************************************/
ControlState_t MotorControl_GetControlState(MotorControl_Motor_t
WhichMotor);
return ControlState Struct for specified motor
/****************************************************************************
* Function
* MotorControl_DriveStraight
*
* Parameters
* MotorControl_Direction_t WhichDirection - Direction to drive in
* (forward or backward)
* uint16_t Speed - target speed to move at in units of 0.1 RPM (5 RPM = 50)
* Max speed is approx 170 RPM
* uint16_t DistanceCM - Ground distance to travel in centimeters
* if set to 0, will drive indefinitely
* Return
* void
* Description
* Drive whole drive train straight forward or backward at set speed for
* specified distance
****************************************************************************/
/****************************************************************************
* Function
* MotorControl_DriveTurn
*
* Parameters
* MotorControl_Turn_t WhichTurn - Direction to turn (clock or counterclock)
* uint16_t Speed - target speed to move at in units of 0.1 RPM (5 RPM = 50)
* Max speed is approx 170 RPM
* uint16_t AngleDeg - Angle in degrees to rotate base by
* if set to 0, will drive indefinitely
* Return
* void
* Description
* Turn whole drive train on the spot by Angle in specified direction and speed
****************************************************************************/
/*
* InitPWMTimer
* Helper Function for InitMotorControl
* Handles configuration of Timer for PWM
*/
/*
* InitLeftMotor
* Helper Function for InitMotorControl
* Handles configuration of ports and OC for Left Motor
*/
static void InitLeftMotor(void)
/*
* InitRightMotor
* Helper Function for InitMotorControl
* Handles configuration of ports and OC for Right Motor
*/
/*
* InitInputCapture
* Helper Function for InitMotorControl
* Handles configuration interrupts, and timers for input capture
*/
/*
* InitLeftEncoder
* Helper Function for InitMotorControl
* Handles configuration of IC and ports for left encoder
*/
/*
* InitRightEncoder
* Helper Function for InitMotorControl
* Handles configuration of IC and ports for Right encoder
*/
static void InitRightEncoder(void)
/*
* InitControlLaw
* Helper Function for InitMotorControl
* Handles configuration of interrupts and timer for control law
*/
Parameters
None
Returns
void
Description
Interrupt Handler for Encoder timer rollover
Notes
Author
* Andrew Sack
****************************************************************************/
If T2IF is pending (there is a small chance that the IC has fired and handled it already)
Increment the rollover counter
Clear the rollover interrupt (timer interrupt flag)
Enable interrupts (OK, since we know interrupts were enabled to get here)
/****************************************************************************
Function
LeftEncoderHandler
Parameters
None
Returns
void
Description
Interrupt Handler for LeftEncoder
Notes
Author
* Andrew Sack
****************************************************************************/
Calculate RPM as float. Only keep if below max value to filter out spikes
// Distance handling
if TargetTickCount is set (not 0)
if TickCount is within margin of TargetTickCount
Set Motor TargetRPM to 0
Set DriveGoalReached to true
Reset TargetTickCount
enable global interrupts
/****************************************************************************
Function
RightEncoderHandler
Parameters
None
Returns
void
Description
Interrupt Handler for RightEncoder
Notes
Author
* Andrew Sack
****************************************************************************/
Calculate RPM as float. Only keep if below max value to filter out spikes
// Distance handling
if TargetTickCount is set (not 0)
if TickCount is within margin of TargetTickCount
Set Motor TargetRPM to 0
Set DriveGoalReached to true
Reset TargetTickCount
enable global interrupts
/****************************************************************************
Function
ControlLawHandler
Parameters
None
Returns
void
Description
Interrupt Handler for Control Law Timer
Notes
Author
* Andrew Sack
****************************************************************************/
if DriveGoalReached
Post DRIVE_GOAL_REACHED event to DriveTrain Service if DriveGoalReached
Clear all DriveGoalActive and DriveGoalReached flags
/****************************************************************************
Function
UpdateControlLaw
Parameters
ControlState_t *ThisControl - Pointer to Control struct for desired motor
Encoder_t *Encoder - Pointer to Encoder struct for desired motor
Returns
void
Description
Helper function for control law
Notes
Author
* Andrew Sack
****************************************************************************/
DRIVE_STOP
Will disable Bumper if active
DRIVE_UNTIL_BUMP
Will enable bumper event checker
BUMP_FOUND
Posted by event checker when press detected
States
BumperIdleState
Bumper event checker disabled
BumperActiveState
Bumper event checker is active and looking for bumper press
Pseudocode
/****************************************************************************
Function
InitBumperService
Parameters
uint8_t : the priorty of this service
Returns
bool, false if error in initialization, true otherwise
Description
Saves away the priority, sets up the initial transition and does any
other required initialization for this state machine
Notes
Author
Andrew Sack
****************************************************************************/
bool InitBumperService(uint8_t Priority)
MyPriority = Priority
CurrentState = BumperIdleState
Set EventCheckerActive to false
Configure Pin for bumper as digital input
Enable pull up on bumper pin
/****************************************************************************
Function
PostBumperService
Parameters
ES_Event_t ThisEvent , the event to post to the queue
Returns
boolean False if the Enqueue operation failed, True otherwise
Description
Posts an event to this state machine's queue
Notes
Author
Andrew Sack
****************************************************************************/
/****************************************************************************
Function
RunBumperService
Parameters
ES_Event_t : the event to process
Returns
ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise
Description
add your description here
Notes
uses nested switch/case to implement the machine.
Author
Andrew Sack
****************************************************************************/
switch on CurrentState
case BumperIdleState:
if EventType is DRIVE_UNTIL_BUMP
EventCheckerActive = true
Init Timer for timeout
Set CurrentState to BumperActiveState
case BumperActiveState:
if EventType is BUMP_FOUND
Post BUMP_FOUND to DriveTrain and SPI
EventCheckerActive = false
Stop Timer
Set CurrentState to BumperIdleState
else if EventType is DRIVE_STOP
EventCheckerActive = false
Stop Timer
Set CurrentState to BumperIdleState
else if EventType is ES_TIMEOUT
Post BUMP_FOUND to DriveTrain and SPI
EventCheckerActive = false
Set CurrentState to BumperIdleState
/****************************************************************************
Function
QueryBumperService
Parameters
None
Returns
BumperState_t The current state of the Bumper state machine
Description
returns the current state of the Bumper state machine
Notes
Author
Andrew Sack
****************************************************************************/
BumperState_t QueryBumperService(void)
return CurrentState
bool Check4Bump(void)
if EventCheckerActive
if bumper pin value is lo (pressed)
post BUMP_FOUND to this service
Set EventCheckerActive to false
return true
return false