diff --git a/back-end/realtime/src/util/WLEDHelper.ts b/back-end/realtime/src/util/WLEDHelper.ts index 7ad46cfa..35e4ac16 100644 --- a/back-end/realtime/src/util/WLEDHelper.ts +++ b/back-end/realtime/src/util/WLEDHelper.ts @@ -21,15 +21,36 @@ export const buildWledSetColorPacket = ( seg: [] }; + const segments = new Map(); + packet.patterns.forEach((pattern) => { - wledJson.seg.push({ - id: pattern.segment, - on: true, - frz: false, - fx: 0, - col: [pattern.color] - }); + if (!pattern.subset) { + segments.set(pattern.segment, { + id: pattern.segment, + on: true, + frz: false, + fx: 0, + col: [pattern.color] + }); + } else { + if (!segments.get(pattern.segment)) { + segments.set(pattern.segment, { + id: pattern.segment, + on: true, + transition: 10, + i: [pattern.subset.startIndex, pattern.subset.endIndex, pattern.color] + }); + } else { + segments + .get(pattern.segment) + .i.push( + pattern.subset.startIndex, + pattern.subset.endIndex, + pattern.color + ); + } + } }); - return JSON.stringify(wledJson); + return JSON.stringify({ seg: Array.from(segments.values()) }); }; diff --git a/lib/models/src/base/FieldControl.ts b/lib/models/src/base/FieldControl.ts index 97e2949b..cc239f07 100644 --- a/lib/models/src/base/FieldControl.ts +++ b/lib/models/src/base/FieldControl.ts @@ -70,6 +70,10 @@ export type HubUpdateParameters = HubParameters< export interface LedPatternUpdateParameters { segment: number; color: string; + subset?: { + startIndex: number; + endIndex: number; + }; } export interface LedSegment { diff --git a/lib/models/src/fcs/FeedingTheFutureFCS.ts b/lib/models/src/fcs/FeedingTheFutureFCS.ts index 6d24a630..172894e9 100644 --- a/lib/models/src/fcs/FeedingTheFutureFCS.ts +++ b/lib/models/src/fcs/FeedingTheFutureFCS.ts @@ -9,6 +9,7 @@ import { import { NexusGoalState } from '../seasons/FeedingTheFuture.js'; import { FeedingTheFuture } from '../seasons/index.js'; import { + applyPartialPatternToStrips, applyPatternToStrips, applySetpointToMotors, LedStrip, @@ -559,65 +560,25 @@ export class PacketManager { const result: FieldControlUpdatePacket = { hubs: {}, wleds: {} }; - switch (currentState) { - case NexusGoalState.Full: - applyPatternToStrips(this.fieldOptions.goalFullColor, [strip], result); - break; - case NexusGoalState.BlueOnly: - applyPatternToStrips( - this.fieldOptions.goalBlueOnlyColor, - [strip], - result - ); - break; - case NexusGoalState.GreenOnly: - applyPatternToStrips( - this.fieldOptions.goalGreenOnlyColor, - [strip], - result - ); - break; - default: - applyPatternToStrips(this.fieldOptions.goalEmptyColor, [strip], result); + if (currentState === NexusGoalState.BlueOnly) { + applyPatternToStrips( + this.fieldOptions.goalBlueOnlyColor, + [strip], + result + ); + } else if (currentState === NexusGoalState.GreenOnly) { + applyPatternToStrips( + this.fieldOptions.goalGreenOnlyColor, + [strip], + result + ); } if ( currentState === NexusGoalState.Full && previousState !== NexusGoalState.Full ) { - // Start timer with callback - this.timers.set( - goal, - setTimeout(() => { - if (!this.matchInProgress) return; - - // Set pattern - const result: FieldControlUpdatePacket = { hubs: {}, wleds: {} }; - applyPatternToStrips('ffffff', [strip], result); - applySetpointToMotors( - this.fieldOptions.foodProductionMotorSetpoint, - [motor], - result - ); - broadcast(result); - - setTimeout(() => { - const result: FieldControlUpdatePacket = { hubs: {}, wleds: {} }; - applySetpointToMotors(0, [motor], result); - broadcast(result); - }, this.fieldOptions.foodProductionMotorDurationMs); - - this.matchEmitter.emit(MatchSocketEvent.MATCH_ADJUST_DETAILS_NUMBER, { - key: `${side}FoodProduced`, - adjustment: 1 - } satisfies NumberAdjustment); - - this.matchEmitter.emit(MatchSocketEvent.MATCH_UPDATE_DETAILS_ITEM, { - key: goal, - value: NexusGoalState.Produced - }); - }, this.fieldOptions.foodProductionDelayMs) - ); + this.funnyLightSequence(motor, strip, side, goal); } else if ( currentState !== NexusGoalState.Full && previousState === NexusGoalState.Full @@ -664,4 +625,76 @@ export class PacketManager { value: balanced } satisfies ItemUpdate); }; + + funnyLightSequence = ( + motor: MotorA, + strip: LedStripA, + side: string, + goal: string + ) => { + const steps = 10; + + const recurse = (count: number, strip: LedStripA) => { + if (!this.matchInProgress) return; + if (count === 0) { + // Set pattern + const result: FieldControlUpdatePacket = { hubs: {}, wleds: {} }; + applyPatternToStrips(this.fieldOptions.goalFullColor, [strip], result); + applySetpointToMotors( + this.fieldOptions.foodProductionMotorSetpoint, + [motor], + result + ); + this.broadcastCallback(result); + + this.timers.set( + goal, + setTimeout(() => { + const result: FieldControlUpdatePacket = { hubs: {}, wleds: {} }; + applySetpointToMotors(0, [motor], result); + this.broadcastCallback(result); + }, this.fieldOptions.foodProductionMotorDurationMs) + ); + + this.matchEmitter.emit(MatchSocketEvent.MATCH_ADJUST_DETAILS_NUMBER, { + key: `${side}FoodProduced`, + adjustment: 1 + } satisfies NumberAdjustment); + + this.matchEmitter.emit(MatchSocketEvent.MATCH_UPDATE_DETAILS_ITEM, { + key: goal, + value: NexusGoalState.Produced + }); + + return; + } + + const middle = Math.floor(23 / 2); + const length = Math.floor(23 / 2 / steps) * (steps - count); + const startIndex = middle - length; + const endIndex = middle + 1 + length; + console.log(`Action ${count} ${startIndex} ${endIndex}`); + + const result: FieldControlUpdatePacket = { hubs: {}, wleds: {} }; + + applyPartialPatternToStrips( + this.fieldOptions.goalFullColor, + startIndex, + endIndex, + [strip], + result + ); + + this.broadcastCallback(result); + + this.timers.set( + goal, + setTimeout(() => { + recurse(count - 1, strip); + }, Math.floor(this.fieldOptions.foodProductionDelayMs / steps)) + ); + }; + + recurse(10, strip); + }; } diff --git a/lib/models/src/fcs/Packets.ts b/lib/models/src/fcs/Packets.ts index 682db3c5..ff575f1b 100644 --- a/lib/models/src/fcs/Packets.ts +++ b/lib/models/src/fcs/Packets.ts @@ -46,6 +46,31 @@ export function applyPatternToStrips( }); } +export function applyPartialPatternToStrips( + color: string, + startIndex: number, + endIndex: number, + strips: LedStrip[], + packet: FieldControlUpdatePacket +): void { + strips.forEach((strip) => { + if (!packet.wleds[strip.controller]) { + packet.wleds[strip.controller] = { + patterns: [] + }; + } + + packet.wleds[strip.controller].patterns.push({ + segment: strip.segment, + color, + subset: { + startIndex, + endIndex + } + }); + }); +} + export function applySetpointToMotors( setpoint: number, motors: Motor[],