diff --git a/front-end/src/seasons/fgc-2024/settings.tsx b/front-end/src/seasons/fgc-2024/settings.tsx
index 4e278852..031837ec 100644
--- a/front-end/src/seasons/fgc-2024/settings.tsx
+++ b/front-end/src/seasons/fgc-2024/settings.tsx
@@ -19,7 +19,6 @@ import {
goalGreenOnlyColorAtom,
goalLedLengthAtom,
matchEndBlueNexusGoalColorAtom,
- matchEndRampColorAtom,
matchEndRedNexusGoalColorAtom,
prepareFieldColorAtom,
rampBalancedColorAtom,
@@ -49,9 +48,6 @@ export const Settings: FC = () => {
useRecoilState(matchEndRedNexusGoalColorAtom);
const [matchEndBlueNexusGoalColor, setMatchEndBlueNexusGoalColor] =
useRecoilState(matchEndBlueNexusGoalColorAtom);
- const [matchEndRampColor, setMatchEndRampColor] = useRecoilState(
- matchEndRampColorAtom
- );
const [redWledWebSocketAddress, setRedWledWebSocketAddress] = useRecoilState(
redWledWebSocketAddressAtom
);
@@ -154,13 +150,6 @@ export const Settings: FC = () => {
format='string'
inline
/>
-
({
effects: [localStorageEffect('ftf.matchEndBlueNexusGoalColor')]
});
-export const matchEndRampColorAtom = atom({
- key: 'ftf.matchEndRampColor',
- default: FeedingTheFutureFCS.defaultFieldOptions.matchEndRampColor,
- effects: [localStorageEffect('ftf.matchEndRampColor')]
-});
-
export const redWledWebSocketAddressAtom = atom({
key: 'ftf.redWledWebSocketAddress',
default: FeedingTheFutureFCS.defaultFieldOptions.redWledWebSocketAddress,
@@ -167,7 +161,6 @@ export const fieldOptionsSelector: RecoilValueReadOnly void;
private matchEmitter: EventEmitter;
private actionQueue = new Map();
- private matchInProgress: boolean = false;
+ private matchState: 'prestart' | 'in progress' | 'ended' | 'aborted' =
+ 'prestart';
+
+ private previousBalanced = true;
public constructor(
fieldOptions: FieldOptions,
@@ -247,7 +250,7 @@ export class PacketManager {
};
public handleAbort = (): void => {
- this.matchInProgress = false;
+ this.matchState = 'aborted';
const result: FieldControlUpdatePacket = { hubs: {}, wleds: {} };
applyPatternToStrips(
@@ -287,7 +290,7 @@ export class PacketManager {
};
public handleMatchStart = (): void => {
- this.matchInProgress = true;
+ this.matchState = 'in progress';
const result: FieldControlUpdatePacket = { hubs: {}, wleds: {} };
applyPatternToStrips(
@@ -309,7 +312,7 @@ export class PacketManager {
};
public handleMatchEnd = (): void => {
- this.matchInProgress = false;
+ this.matchState = 'ended';
const result: FieldControlUpdatePacket = { hubs: {}, wleds: {} };
applyPatternToStrips(
@@ -322,11 +325,10 @@ export class PacketManager {
LedStripA.ALL_RED_GOALS,
result
);
- applyPatternToStrips(
- this.fieldOptions.matchEndRampColor,
- [LedStripA.RAMP],
- result
- );
+
+ // Don't apply pattern to ramp. Keep current state and allow future updates
+ // directly from digital input
+
applySetpointToMotors(0, MotorA.ALL_GOALS, result);
this.broadcastCallback(result);
@@ -348,7 +350,7 @@ export class PacketManager {
currentDetails: FeedingTheFuture.MatchDetails,
broadcast: (update: FieldControlUpdatePacket) => void
) => {
- if (!this.matchInProgress) return;
+ if (this.matchState !== 'in progress') return;
this.handleGoalStateChange(
previousDetails.redNexusState.CW1,
@@ -567,12 +569,6 @@ export class PacketManager {
'blue',
broadcast
);
-
- this.handleRampStateChange(
- previousDetails.fieldBalanced,
- currentDetails.fieldBalanced,
- broadcast
- );
};
private handleGoalStateChange = (
@@ -622,46 +618,42 @@ export class PacketManager {
broadcast(result);
};
- private handleRampStateChange = (
- previousBalanced: number,
- currentBalanced: number,
- broadcast: (update: FieldControlUpdatePacket) => void
- ) => {
- if (currentBalanced === previousBalanced) return;
+ public handleDigitalInputs = (packet: DigitalInputsResult) => {
+ const balanced = (packet.hubs[RevHub.CENTER_CONTROL_HUB] & 0x1) !== 1;
+
+ if (balanced === this.previousBalanced) return;
- // clearTimeout(this.timers.get('ramp'));
this.actionQueue.delete('ramp');
- const hysteresisWindowMs = currentBalanced
+ const hysteresisWindowMs = balanced
? this.fieldOptions.rampBalancedHysteresisWindowMs
: this.fieldOptions.rampUnbalancedHysteresisWindowMs;
this.actionQueue.set('ramp', {
timestamp: Date.now() + hysteresisWindowMs,
callback: () => {
- const result: FieldControlUpdatePacket = { hubs: {}, wleds: {} };
- applyPatternToStrips(
- currentBalanced
- ? this.fieldOptions.rampBalancedColor
- : this.fieldOptions.rampUnbalancedColor,
- [LedStripA.RAMP],
- result
- );
- broadcast(result);
+ if (this.matchState === 'in progress') {
+ this.matchEmitter.emit(MatchSocketEvent.MATCH_UPDATE_DETAILS_ITEM, {
+ key: 'fieldBalanced',
+ value: balanced
+ } satisfies ItemUpdate);
+ }
+
+ if (this.matchState !== 'prestart' && this.matchState !== 'aborted') {
+ const result: FieldControlUpdatePacket = { hubs: {}, wleds: {} };
+ applyPatternToStrips(
+ balanced
+ ? this.fieldOptions.rampBalancedColor
+ : this.fieldOptions.rampUnbalancedColor,
+ [LedStripA.RAMP],
+ result
+ );
+ this.broadcastCallback(result);
+ }
}
});
};
- public handleDigitalInputs = (packet: DigitalInputsResult) => {
- if (!this.matchInProgress) return;
-
- const balanced = (packet.hubs[RevHub.CENTER_CONTROL_HUB] & 0x1) !== 1;
- this.matchEmitter.emit(MatchSocketEvent.MATCH_UPDATE_DETAILS_ITEM, {
- key: 'fieldBalanced',
- value: balanced
- } satisfies ItemUpdate);
- };
-
runFoodProductionSequence = (
motor: MotorA,
strip: LedStripA,
@@ -671,7 +663,7 @@ export class PacketManager {
const steps = 10;
const recurse = (count: number) => {
- if (!this.matchInProgress) return;
+ if (this.matchState !== 'in progress') return;
// Base state. Food production is over, dispense food and update lights
if (count === 0) {
@@ -761,7 +753,6 @@ export interface FieldOptions {
fieldFaultColor: string;
matchEndRedNexusGoalColor: string;
matchEndBlueNexusGoalColor: string;
- matchEndRampColor: string;
redWledWebSocketAddress: string;
blueWledWebSocketAddress: string;
centerWledWebSocketAddress: string;
@@ -789,7 +780,6 @@ export const defaultFieldOptions: FieldOptions = {
fieldFaultColor: 'ff0000',
matchEndRedNexusGoalColor: 'ff0000',
matchEndBlueNexusGoalColor: '0000ff',
- matchEndRampColor: 'ff00ff',
redWledWebSocketAddress: '',
blueWledWebSocketAddress: '',
centerWledWebSocketAddress: '',