Software Overview
The game is controlled by a pair of C32's, each responsible for different parts of the game. The first C32 has 5 state machines controlling Player 1's game flow, gun debouncing, foot debouncing, the yetis, and Player 1 communication. The second C32 has 6 state machines and 1 service controlling Player 2 game flow, keycard debounce, gun debounce, foot debounce, foot LED lighting patterns, Player2 communication, and environmental effects (servo motions and day/night lighting). Both C32's run event checks that continuously poll for events and feed them to the state machines. The Events and Services Framework 2.2 is used to organize the state machines. The input/output pins of the C32's are shown below, as well as pseduocode and downloadable code files.
Pseudocode
team17-pseudocode.docx | |
File Size: | 29 kb |
File Type: | docx |
Gun Debounce SM
This module is a simple debouncing state machine for yeti hit detection, to ensure multiple hits aren't recorded in a short time span.
Events received: ES_TIMEOUT sent by framework when debounce timer expires, HIT_DETECTED send by gun event checker when player scores a yeti hit.
Events sent: Increase Player Score Event sent to EnvironmentService (to augment the score), GameStart state machines for syncing up at the beginning, and Yeti state machine for lowering the hit yeti.
Events received: ES_TIMEOUT sent by framework when debounce timer expires, HIT_DETECTED send by gun event checker when player scores a yeti hit.
Events sent: Increase Player Score Event sent to EnvironmentService (to augment the score), GameStart state machines for syncing up at the beginning, and Yeti state machine for lowering the hit yeti.
Foot Debounce SM
This is a simple state machine for debouncing foot score signals, to ensure we don't rack up multiple foot scores for one step. Both C32s run this state machine.
Events received: ES_TIMEOUT sent by framework when foot debounce timer expires, Increase or Decrease player score event sent by event checker when player scores a valid foot step.
Events sent: Increase or Decrease Player Score Event sent to EnvironmentService (to augment the score).
Events received: ES_TIMEOUT sent by framework when foot debounce timer expires, Increase or Decrease player score event sent by event checker when player scores a valid foot step.
Events sent: Increase or Decrease Player Score Event sent to EnvironmentService (to augment the score).
Keycard Debounce SM
This is a simple state machine for debouncing the keycard reader, to ensure that one insertion doesn't appear to be multiple insertions and removals. Only player 2's C32 has this.
Events received: ES_TIMEOUT sent by framework when key debounce timer expires, Keycard_maybe_out event sent by event checker when card is not detected in slot reader.
Events sent: Keycard_out event sent to EnvironmentService (to cause a system reset).
Events received: ES_TIMEOUT sent by framework when key debounce timer expires, Keycard_maybe_out event sent by event checker when card is not detected in slot reader.
Events sent: Keycard_out event sent to EnvironmentService (to cause a system reset).
Yeti SM
This state machine controls the two yeti movements, which are both controlled by player 1's C32. Initially, the game starts in the WaitForCard state with the yetis down. Upon insertion of a keycard, we move to the WaitForSync state and the yetis pop up with their eyes glowing and emitters on. Each player needs to shoot their respective yeti to indicate they are ready to start. When this state machine receives a score increase notice from either player, it will move the corresponding yeti down. When it receives a players synced event from the other C32, it moves to WaitForNight state, in which it is waiting for the nighttime phase to begin. During this time, there will be no yeti action. Once the stomping phase (day jump timer) is over, a yeti start event will be received, the nighttime timer starts ticking and we can move to two alternating states (yeti 1 active and yeti 2 active) which will take turns popping up a yeti and moving it down when it has been hit. When the nighttime timer expires, we can move both yetis down, and there will be no more yeti action for the rest of the game. We move to a Yeti_Neutralized state that does not respond to external stimuli. The state machine will be reset when the game ends.
Events received: RUMBLE_ON event sent by GameStartP2 state machine, to indicate the card has been inserted and sync mode should start. Increase P1/P2 Score Event sent by event gun debouncer state machine when a yeti has been hit. Players Synced event sent by GameStartP2 state machine when sync is complete. Yeti_start event sent by GameStartP1 state machine when night falls. ES_TIMEOUT sent by framework when night timer expires.
Events sent: None
Events received: RUMBLE_ON event sent by GameStartP2 state machine, to indicate the card has been inserted and sync mode should start. Increase P1/P2 Score Event sent by event gun debouncer state machine when a yeti has been hit. Players Synced event sent by GameStartP2 state machine when sync is complete. Yeti_start event sent by GameStartP1 state machine when night falls. ES_TIMEOUT sent by framework when night timer expires.
Events sent: None
P1 Game Flow SM
This state machine dictates the flow of the game phases for player 1. We start in a waiting mode until a card insertion event (RUMBLE_ON) is detected, in which case we move to a wait for sync mode. When we receive notice that the players are synced, we move to a game start phase in which the players will be doing basic walking. A timer (Daywalk timer) is set to indicate when we should move to the next phase. Upon expiration of the timer, we move to a score negation phase, during which the player can lower the other player's score. A timer (Day jump) is started upon entering this phase, and when it expires we move to the Yeti phase. This phase does not respond to stimuli and is essentially waiting for the end of the game.
Though the majority of these states actually do not produce any events, they exist so that other state machines and event checkers can check the current phase of the game and perform phase-specific actions.
Events received: RUMBLE_ON event sent by GameStartP2 state machine, to indicate the card has been inserted and sync mode should start. Players Synced event sent by GameStartP2 state machine when sync is complete. ES_TIMEOUT sent by framework when day walking timer or day jumping timer expires.
Events sent: Players synced event sent to Yeti state machine.
Though the majority of these states actually do not produce any events, they exist so that other state machines and event checkers can check the current phase of the game and perform phase-specific actions.
Events received: RUMBLE_ON event sent by GameStartP2 state machine, to indicate the card has been inserted and sync mode should start. Players Synced event sent by GameStartP2 state machine when sync is complete. ES_TIMEOUT sent by framework when day walking timer or day jumping timer expires.
Events sent: Players synced event sent to Yeti state machine.
P2 Game Flow SM
This state machine has a similar purpose as the player 1 game flow machine, except that player 2's C32 is responsible for determining synchronization. We start in a wait for card more, and upon insertion of a card, we move to a syncing mode. Here we sit until we receive notification that both players have shot their starting yetis. We send a player synced message to the other C32 along with other services, set the difficulty level based on the position of the analog difficulty dial, and move to the game start state. The rest of the states progress similarly to the player 1 game flow machine.
Events received: KEYCARD_CHECKIN sent by keycard debouncer. Increase P1 Score or Increase P2 Score events sent by gun debouncer during sync phase. ES_TIMEOUT sent by framework when day walking timer or day jumping timer expires.
Events sent: RUMBLE_ON event sent to GameStartP1 state machine to indicate card insertion. Players Synced event sent to EnvironmentalService to start background effects, also sent to GameStartP1 state machine to indicate sync complete/game starting, and to Foot LED state machine to indicate lights should start flashing.
Events received: KEYCARD_CHECKIN sent by keycard debouncer. Increase P1 Score or Increase P2 Score events sent by gun debouncer during sync phase. ES_TIMEOUT sent by framework when day walking timer or day jumping timer expires.
Events sent: RUMBLE_ON event sent to GameStartP1 state machine to indicate card insertion. Players Synced event sent to EnvironmentalService to start background effects, also sent to GameStartP1 state machine to indicate sync complete/game starting, and to Foot LED state machine to indicate lights should start flashing.
Foot LED Pattern SM
This state machine is executed by player 2, and controls the lighting patters of the foot LEDs that the players are supposed to follow. We start in a wait for sync mode, and then when we get notification that we are synced, we move to the first pattern, which is alternating left foot and right foot states. In each state the corresponding foot LED is lit, and a timer is set to control how long we stay in this state. When the day walking phase is over (indicated by a timer event set from the game flow SM), we switch to the foot stomping pattern, which has a double stomp on each leg. We call this a "neg" pattern because successful stomps will decrease the score of the other player. At some point, the day jump timer will expire, indicating that we should go back to the alternating steps for the rest of the game. The main game timer should expire at some point during the alternating walk pattern, indicating the game is over and the lights should turn off permanently.
Events received: PLAYERS_SYNCED event sent by GameStartP2 state machine to indicate game is starting and foot lights should start flashing. ES_TIMEOUT sent by framework when day walking timer, day jumping timer, main timer, or foot timer expires.
Events sent: None
Events received: PLAYERS_SYNCED event sent by GameStartP2 state machine to indicate game is starting and foot lights should start flashing. ES_TIMEOUT sent by framework when day walking timer, day jumping timer, main timer, or foot timer expires.
Events sent: None
Comm State Machine
This communications state machine is used by both C32's to communicate events to each other. We have 3 data lines linking the C32's that can send a total of 8 different messages, along with a strobe line to indicate an intent to send data, as well as an ack line to show that the data was received.
We start in idle mode, and can move to a sending state if a send request event is received. If the strobe is high we have to defer the request because the other C32 is trying to send data at the moment. If the strobe is low, it means we can go ahead and set the datalines, raise the strobe, and move to a wait for ack stage. During this stage, if we receive any more send requests, we can defer them since we're busy at the moment. If we don't get an ack in a set amount of time, we repost the event and move back to idle state. If we do get the ack, we can lower the strobe and move back to idle state to handle any deferred cases or new ones.
On the other hand, if we sense that the strobe is rising, we know the the other C32 is trying to send data, so we read the datalines and process the message, and raise the ack line. We then move to a wait for strobe fall state, where we only transition back to idle once the other C32 lowers the strobe line. Any send requests received here are also deferred.
Diagram provided courtesy of Ed Carryer's ME218A notes.
We start in idle mode, and can move to a sending state if a send request event is received. If the strobe is high we have to defer the request because the other C32 is trying to send data at the moment. If the strobe is low, it means we can go ahead and set the datalines, raise the strobe, and move to a wait for ack stage. During this stage, if we receive any more send requests, we can defer them since we're busy at the moment. If we don't get an ack in a set amount of time, we repost the event and move back to idle state. If we do get the ack, we can lower the strobe and move back to idle state to handle any deferred cases or new ones.
On the other hand, if we sense that the strobe is rising, we know the the other C32 is trying to send data, so we read the datalines and process the message, and raise the ack line. We then move to a wait for strobe fall state, where we only transition back to idle once the other C32 lowers the strobe line. Any send requests received here are also deferred.
Diagram provided courtesy of Ed Carryer's ME218A notes.
Environment Service
This service handled all of the miscellaneous things involving the game state. It receives events from event checkers or other state machines, and executes specific functions as a result. At the start of the game, after players are synchronized, it will start rotating the sun/moon servo. When it receives scoring events, it calculates the new player scores and adjusts the climber servos accordingly. As various timers expire for the different phases, this service will turn the day and night lights on or off. When the main timer expires indicating the end of the game, the scores are compared, and the winning player will have his/her climber moved to the top, and the corresponding flag raised. Then after a brief delay, all initialization routines are called, effectively resetting the game.
C32 Input/Output Assignments
We tried to minimize the number of pins needed by each C32 to simplify the coding. Player 1's C32 has the requisite comm pins along with 3 inputs (left foot score, right foot score, yeti hit detected) and 2 outputs (move yeti 1 up, move yeti 2 up). Note that the determination of whether a foot scored is done in hardware instead of software - we use logic gates to send a signal if a foot step was detected at the same time that the corresponding LED was lit.
Player 2 has 5 inputs (analog difficulty knob level, yeti hit detected, left foot score, right foot score, key card inserted), 4 servo outputs (moving climbers 1 and 2, rotating the sun/moon, and rotating the flags), and 4 LED outputs (daytime lights, nighttime lights, left foot and right foot lights).
Player 2 has 5 inputs (analog difficulty knob level, yeti hit detected, left foot score, right foot score, key card inserted), 4 servo outputs (moving climbers 1 and 2, rotating the sun/moon, and rotating the flags), and 4 LED outputs (daytime lights, nighttime lights, left foot and right foot lights).
Code Downloads
player_1.zip | |
File Size: | 52 kb |
File Type: | zip |
player_2.zip | |
File Size: | 67 kb |
File Type: | zip |