public void Track() { if (this.State == RotorState.Idle) { this.State = RotorState.TrackSunPrevDir; } }
/// <summary> /// Adjusts the position of the rotor (or one of the auxillary rotot) /// </summary> /// <param name="offset">offset in degree</param> /// <param name="auxId">if not 0, adjusts the position of an auxillary rotor instead</param> public void Adjust(float offset, int auxId = 0) { if (auxId == 0) { this.adjustTarget = this.mainRotor.Angle + MathHelper.ToRadians(offset); this.State = RotorState.Adjust; } else if (this.rotors != null) { foreach (SolarRotor rotor in this.rotors) { if (this.State != RotorState.Adjust) { this.State = RotorState.AdjustAux; } if (rotor.id.AuxNumber == auxId) { rotor.Adjust(offset); } else { rotor.State = this.ifNotNightMode(); } } } }
void update(bool nightMode, bool isAux) { this.nightMode = nightMode; this.State = this.getNextDayState(isAux); this.previousOutput = this.MaxOutput; if (this.previousOutput > this.maxObservedOutput) { this.maxObservedOutput = this.previousOutput; } }
RotorState ifNotNightMode(RotorState state = RotorState.Idle) => this.nightMode ? RotorState.NightIdle : state;
RotorState delayState(RotorState state, int delay = 1) => this.counter > delay ? state : this.State;
void enterState(RotorState state) { this.log($"{this.state} {state}"); this.counter = this.State != state ? 0 : this.counter + 1; switch (state) { case RotorState.Idle: this.stop(); foreach (SolarRotor r in this.rotors ?? Enumerable.Empty <SolarRotor>()) { r.State = RotorState.Idle; } break; case RotorState.TrackSunPrevDir: case RotorState.TrackSunPrevDirConfirmed: case RotorState.TrackSunRevDir: case RotorState.TrackSunRevDirConfirmed: this.rotate(this.previousLock.Direction ^ (this.State == RotorState.TrackSunRevDir || this.State == RotorState.TrackSunRevDirConfirmed)); break; case RotorState.TrackSunAux: this.stop(); if (this.State != RotorState.TrackSunAux) { this.updateAux(); } else { this.updateAux(r => r.State != RotorState.Idle); } break; case RotorState.ResetPrevious: this.goTo(this.previousLock.Position); break; case RotorState.GoIdle: this.stop(); this.previousLock = new SolarOutput(this.CurrentOutput, this.MaxOutput, this.mainRotor.Angle, this.mainRotor.AngleProxy(this.previousLock.Position) < 0); if (this.firstLockOfTheDay) { this.log("First lock of the day: saving position"); this.firstLockOfTheDay = false; this.resetAngle = this.previousLock.Position; } break; case RotorState.Adjust: if (this.State == RotorState.NightIdle) { this.resetAngle = this.adjustTarget; } else if (this.State != RotorState.Adjust) { this.previousLock = new SolarOutput(this.previousLock.Output, this.previousLock.MaxOutput, this.adjustTarget, this.previousLock.Direction); } this.goTo(this.adjustTarget); break; case RotorState.AdjustAux: this.stop(); this.updateAux(r => r.State == RotorState.Adjust); foreach (SolarRotor rotor in this.rotors.Where(r => r.State != RotorState.Adjust)) { rotor.State = this.ifNotNightMode(); } break; case RotorState.NightIdle: this.firstLockOfTheDay = true; this.goTo(this.resetAngle); this.updateAux(); break; } this.state = state; }