def sweep (self): self.part ('Timers') self.regularPhaseTimer.reset (self.regularPhaseTimer > self.tEastWestBlink or self.cycleMode or self.nightMode or self.offMode) self.cyclePhaseTimer.reset (self.cyclePhaseTimer > self.tWestBlink or self.regularMode or self.nightMode or self.offMode) self.blinkTimer.reset (self.blinkTimer > self.tBlink) self.blinkPulse.trigger (self.blinkTimer == 0) self.blink.mark (not self.blink, self.blinkPulse) self.part ('Mode switching') self.modePulse.trigger (self.modeButton) self.modeStep.set ((self.modeStep + 1) % 4, self.modePulse) self.regularMode.mark (self.modeStep == 0) self.cycleMode.mark (self.modeStep == 1) self.nightMode.mark (self.modeStep == 2) self.offMode.mark (self.modeStep == 3) self.part ('Regular mode phases') self.northSouthGreen.mark (0 < self.regularPhaseTimer < self.tNorthSouthGreen) self.northSouthBlink.mark (self.tNorthSouthGreen < self.regularPhaseTimer < self.tNorthSouthBlink) self.eastWestGreen.mark (self.tNorthSouthBlink < self.regularPhaseTimer < self.tEastWestGreen) self.eastWestBlink.mark (self.tEastWestGreen < self.regularPhaseTimer) self.part ('Cycle mode phases') self.northGreen.mark (0 < self.cyclePhaseTimer < self.tNorthGreen) self.northBlink.mark (self.tNorthGreen < self.cyclePhaseTimer < self.tNorthBlink) self.eastGreen.mark (self.tNorthBlink < self.cyclePhaseTimer < self.tEastGreen) self.eastBlink.mark (self.tEastGreen < self.cyclePhaseTimer < self.tEastBlink) self.southGreen.mark (self.tEastBlink < self.cyclePhaseTimer < self.tSouthGreen) self.southBlink.mark (self.tSouthGreen < self.cyclePhaseTimer < self.tSouthBlink) self.westGreen.mark (self.tSouthBlink < self.cyclePhaseTimer < self.tWestGreen) self.westBlink.mark (self.tWestGreen < self.cyclePhaseTimer) self.part ('Traffic lamps') self.northGreenLamp.mark (self.northSouthGreen or self.northGreen) self.northYellowLamp.mark ((self.northSouthBlink or self.northBlink or self.nightMode) and self.blink) self.northRedLamp.mark (not (self.northSouthGreen or self.northGreen or self.northSouthBlink or self.northBlink or self.nightMode or self.offMode)) self.eastGreenLamp.mark (self.eastWestGreen or self.eastGreen) self.eastYellowLamp.mark ((self.eastWestBlink or self.eastBlink or self.nightMode) and self.blink) self.eastRedLamp.mark (not (self.eastWestGreen or self.eastGreen or self.eastWestBlink or self.eastBlink or self.nightMode or self.offMode)) self.southGreenLamp.mark (self.northSouthGreen or self.southGreen) self.southYellowLamp.mark ((self.northSouthBlink or self.southBlink or self.nightMode) and self.blink) self.southRedLamp.mark (not (self.northSouthGreen or self.southGreen or self.northSouthBlink or self.southBlink or self.nightMode or self.offMode)) self.westGreenLamp.mark (self.eastWestGreen or self.westGreen) self.westYellowLamp.mark ((self.eastWestBlink or self.westBlink or self.nightMode) and self.blink) self.westRedLamp.mark (not (self.eastWestGreen or self.westGreen or self.eastWestBlink or self.westBlink or self.nightMode or self.offMode)) self.part ('Street illumination') self.brightPulse.trigger (self.brightButton) self.brightDirection.mark (not self.brightDirection, self.brightPulse) self.brightDelta.set (-self.brightFluxus * sp.world.period, self.brightDirection, self.brightFluxus * sp.world.period) self.streetLamp.set (sp.limit (self.streetLamp + self.brightDelta, self.brightMin, self.brightMax), self.brightButton)
def sweep(self): self.part('Torso') self.torTorq.set(sp.limit(self.torGain * self.torVolt, self.torMax), self.torEnab, 0) self.torBrake.mark(not self.torEnab) self.torAccel.set(self.torSpeed / -sp.world.period, self.torBrake, self.torTorq / self.torInert) self.torSpeed.set(self.torSpeed + self.torAccel * sp.world.period) self.torAng.set(self.torAng + self.torSpeed * sp.world.period) self.part('upper arm') self.uppTorq.set(sp.limit(self.uppGain * self.uppVolt, self.uppMax), self.uppEnab, 0) self.uppBrake.mark(not self.uppEnab) self.uppAccel.set(self.uppSpeed / -sp.world.period, self.uppBrake, self.uppTorq / self.uppInert) self.uppSpeed.set(self.uppSpeed + self.uppAccel * sp.world.period) self.uppAng.set(self.uppAng + self.uppSpeed * sp.world.period) self.part('fore arm') self.forTorq.set(sp.limit(self.forGain * self.forVolt, self.forMax), self.forEnab, 0) self.forBrake.mark(not self.forEnab) self.forAccel.set(self.forSpeed / -sp.world.period, self.forBrake, self.forTorq / self.forInert) self.forSpeed.set(self.forSpeed + self.forAccel * sp.world.period) self.forAng.set(self.forAng + self.forSpeed * sp.world.period) self.part('wrist') self.wriTorq.set(sp.limit(self.wriGain * self.wriVolt, self.wriMax), self.wriEnab, 0) self.wriBrake.mark(not self.wriEnab) self.wriAccel.set(self.wriSpeed / -sp.world.period, self.wriBrake, self.wriTorq / self.wriInert) self.wriSpeed.set(self.wriSpeed + self.wriAccel * sp.world.period) self.wriAng.set(self.wriAng + self.wriSpeed * sp.world.period) self.part('hand and fingers') self.hanAng.set(self.hanAngSet, self.hanEnab) self.finAng.set(self.finAngSet, self.finEnab)
def sweep(self): self.local_sail_angle.set(self.local_sail_angle - 1, self.local_sail_angle > self.target_sail_angle) self.local_sail_angle.set(self.local_sail_angle + 1, self.local_sail_angle < self.target_sail_angle) self.global_sail_angle.set((self.sailboat_rotation + self.local_sail_angle + 180) % 360) self.gimbal_rudder_angle.set(self.gimbal_rudder_angle - 1, self.gimbal_rudder_angle > self.target_gimbal_rudder_angle) self.gimbal_rudder_angle.set(self.gimbal_rudder_angle + 1, self.gimbal_rudder_angle < self.target_gimbal_rudder_angle) if not self.pause: # Calculate forward force in N based on the angle between the sail and the wind self.sail_alpha.set(sp.abs(self.global_sail_angle - sp.world.wind.wind_direction) % 360) self.sail_alpha.set(sp.abs(180 - self.sail_alpha) % 360, self.sail_alpha > 90) self.boot_wind.set(self.forward_velocity) self.alfa.set(sp.world.wind.wind_direction - self.sailboat_rotation) # headforce = sail area * wind pressure # wind pressure = 0.613 * wind speed ^ 2 self.head_wind_force.set(2 * 0.613 * 2 * self.forward_velocity) #bereken de kracht van de apparent wind door de echte wind te gebruiken en de rotatie van de boot self.apparent_wind.set(sp.sqrt(sp.world.wind.wind_scalar * sp.world.wind.wind_scalar + self.head_wind_force * self.head_wind_force + 2 * sp.world.wind.wind_scalar * self.head_wind_force * sp.cos(self.alfa))) #bereken de hoek van de apparent wind aan de hand van de echte wind en de rotatie van de boot self.apparent_wind_angle.set(sp.acos(round((sp.world.wind.wind_scalar * sp.cos(self.alfa) + self.head_wind_force) / self.apparent_wind, 2))) # print(round((sp.world.wind.wind_scalar * sp.cos(self.alfa) + self.forward_velocity) / self.apparent_wind, 2)) self.perpendicular_sail_force.set(self.apparent_wind * sp.sin(self.sail_alpha)) self.forward_sail_force.set(self.perpendicular_sail_force * sp.sin(self.local_sail_angle)) self.forward_sail_force.set(sp.abs(self.forward_sail_force)) self.drag.set((0.83 * self.forward_velocity - 0.38)) if self.drag < 0: self.drag.set(0) # Sailing against wind min_threshold = (self.global_sail_angle - 180) % 360 max_threshold = (self.global_sail_angle + 180) % 360 self.forward_sail_force.set(self.forward_sail_force, is_sailing_against_wind(min_threshold, max_threshold, self.local_sail_angle, self.global_sail_angle, sp.world.wind.wind_direction)) # Newton's second law self.drag_deacceleration.set(self.drag / self.mass) self.acceleration.set((self.forward_sail_force / self.mass) - self.drag_deacceleration) self.forward_velocity.set(sp.limit(self.forward_velocity + self.acceleration * sp.world.period, 20)) # Splitting forward velocity vector into vertical and horizontal components self.vertical_velocity.set(sp.sin(self.sailboat_rotation) * self.forward_velocity) self.horizontal_velocity.set(sp.cos(self.sailboat_rotation) * self.forward_velocity) self.position_x.set(self.position_x + self.horizontal_velocity * 0.001) self.position_y.set(self.position_y + self.vertical_velocity * 0.001) self.rotation_speed.set(0.001 * self.gimbal_rudder_angle * self.forward_velocity) self.sailboat_rotation.set((self.sailboat_rotation - self.rotation_speed) % 360) self.boot_direction.set(180 + self.sailboat_rotation) self.head_wind_direction.set((self.boot_direction + 180) % 360) if sp.world.wind.wind_direction <= self.head_wind_direction: self.true_apparent_wind.set((self.head_wind_direction - self.apparent_wind_angle) % 360) else: self.true_apparent_wind.set((self.head_wind_direction + self.apparent_wind_angle) % 360)
def sweep(self): self.local_sail_angle.set( self.local_sail_angle - 1, self.local_sail_angle > self.target_sail_angle) self.local_sail_angle.set( self.local_sail_angle + 1, self.local_sail_angle < self.target_sail_angle) self.global_sail_angle.set( (self.sailboat_rotation + self.local_sail_angle + 180) % 360) self.gimbal_rudder_angle.set( self.gimbal_rudder_angle - 1, self.gimbal_rudder_angle > self.target_gimbal_rudder_angle) self.gimbal_rudder_angle.set( self.gimbal_rudder_angle + 1, self.gimbal_rudder_angle < self.target_gimbal_rudder_angle) if not self.pause: # Calculate forward force in N based on the angle between the sail and the wind self.sail_alpha.set( sp.abs(self.global_sail_angle - sp.world.wind.wind_direction) % 360) self.sail_alpha.set( sp.abs(180 - self.sail_alpha) % 360, self.sail_alpha > 90) self.perpendicular_sail_force.set(sp.world.wind.wind_scalar * sp.sin(self.sail_alpha)) self.forward_sail_force.set(self.perpendicular_sail_force * sp.sin(self.local_sail_angle)) self.forward_sail_force.set(sp.abs(self.forward_sail_force)) # Sailing against wind min_threshold = (self.global_sail_angle - 180) % 360 max_threshold = (self.global_sail_angle + 180) % 360 self.forward_sail_force.set( 0, is_sailing_against_wind(min_threshold, max_threshold, self.local_sail_angle, self.global_sail_angle, sp.world.wind.wind_direction)) # Newton's second law self.drag.set(self.forward_velocity * 0.05) self.acceleration.set(self.forward_sail_force / self.mass - self.drag) self.forward_velocity.set( sp.limit( self.forward_velocity + self.acceleration * sp.world.period, 8)) # Splitting forward velocity vector into vertical and horizontal components self.vertical_velocity.set( sp.sin(self.sailboat_rotation) * self.forward_velocity) self.horizontal_velocity.set( sp.cos(self.sailboat_rotation) * self.forward_velocity) self.position_x.set(self.position_x + self.horizontal_velocity * 0.001) self.position_y.set(self.position_y + self.vertical_velocity * 0.001) self.rotation_speed.set(0.001 * self.gimbal_rudder_angle * self.forward_velocity) self.sailboat_rotation.set( (self.sailboat_rotation - self.rotation_speed) % 360)
def sweep(self): self.part('gimbal angle blue/yellow') self.blueYellowRoughAngle.set( sp.limit( self.blueYellowRoughAngle + self.blueYellowDelta * self.thrusterTiltSpeed * sp.world.period, self.thrusterMaxAngle)) self.blueYellowAngle.set(sp.snap(self.blueYellowRoughAngle, 0, 3)) self.part('thruster angle green/red') self.greenRedRoughAngle.set( sp.limit( self.greenRedRoughAngle + self.greenRedDelta * self.thrusterTiltSpeed * sp.world.period, self.thrusterMaxAngle)) self.greenRedAngle.set(sp.snap(self.greenRedRoughAngle, 0, 3)) self.part('fuel throttle') self.throttlePercent.set( sp.limit( self.throttlePercent + self.throttleDelta * self.throttleSpeed * sp.world.period, 0, 100)) self.thrust.set(self.throttlePercent * self.thrusterMaxForce / 100) self.part('linear movement') thrusterForceVec = np.array((0, 0, self.thrust())) if cm.useQuaternions: thrusterRotQuat = sp.quatMul( sp.quatFromAxAng(np.array((1, 0, 0)), self.blueYellowAngle), sp.quatFromAxAng(np.array((0, 1, 0)), -self.greenRedAngle)) shipForceVec = sp.quatVecRot(thrusterRotQuat, thrusterForceVec) else: # Local coord sys, so "forward" order thrusterRotMat = tf.getRotXMat( self.blueYellowAngle) @ tf.getRotYMat(-self.greenRedAngle) shipForceVec = thrusterRotMat @ thrusterForceVec self.forwardThrust.set(shipForceVec[2]) self.blueYellowThrust.set(shipForceVec[1]) self.greenRedThrust.set(shipForceVec[0]) if cm.useQuaternions: worldForceVec = sp.quatVecRot(self._shipRotQuat, shipForceVec) else: worldForceVec = self._shipRotMat @ shipForceVec self.thrustX.set(worldForceVec[0]) self.thrustY.set(worldForceVec[1]) self.thrustZ.set(worldForceVec[2]) earthGravVec = cm.getGravVec( self.shipMass, cm.earthMass, cm.earthDiam, sp.tEva((self.positionX, self.positionY, self.positionZ))) self.earthGravX.set(earthGravVec[0]) self.earthGravY.set(earthGravVec[1]) self.earthGravZ.set(earthGravVec[2]) moonGravVec = cm.getGravVec( self.shipMass, cm.moonMass, cm.moonDiam, sp.tSub(sp.tEva((self.positionX, self.positionY, self.positionZ)), (0, 0, cm.earthMoonDist))) self.moonGravX.set(moonGravVec[0]) self.moonGravY.set(moonGravVec[1]) self.moonGravZ.set(moonGravVec[2]) self.totalForceX.set(self.thrustX + self.earthGravX + self.moonGravX) self.totalForceY.set(self.thrustY + self.earthGravY + self.moonGravY) self.totalForceZ.set(self.thrustZ + self.earthGravZ + self.moonGravZ) self.linAccelX.set(self.totalForceX / self.shipMass) self.linAccelY.set(self.totalForceY / self.shipMass) self.linAccelZ.set(self.totalForceZ / self.shipMass) self.linVelocX.set(self.linVelocX + self.linAccelX * sp.world.period) self.linVelocY.set(self.linVelocY + self.linAccelY * sp.world.period) self.linVelocZ.set(self.linVelocZ + self.linAccelZ * sp.world.period) self.positionX.set(self.positionX + self.linVelocX * sp.world.period) self.positionY.set(self.positionY + self.linVelocY * sp.world.period) self.positionZ.set(self.positionZ + self.linVelocZ * sp.world.period) self.part('angular movement') rSq = self.effectiveRadius * self.effectiveRadius hSq = self.effectiveHeight * self.effectiveHeight # Source: https://en.wikipedia.org/wiki/List_of_moments_of_inertia#List_of_3D_inertia_tensors shipInertMat = self.shipMass() / 12 * np.array( (((3 * rSq + hSq) / 12, 0, 0), (0, (3 * rSq + hSq) / 12, 0), (0, 0, rSq / 6))) invInertMat = np.linalg.inv( self._shipRotMat @ shipInertMat @ self._shipRotMat.T) self.blueYellowTorque.set(self.blueYellowThrust * self.effectiveHeight / 2) self.greenRedTorque.set(-self.greenRedThrust * self.effectiveHeight / 2) shipTorqueVec = np.array( (self.blueYellowTorque(), self.greenRedTorque(), 0)) if cm.useQuaternions: rawTorqueVec = sp.quatVecRot(self._shipRotQuat, shipTorqueVec) else: rawTorqueVec = self._shipRotMat @ shipTorqueVec self.torqueX.set(rawTorqueVec[0]) self.torqueY.set(rawTorqueVec[1]) self.torqueZ.set(rawTorqueVec[2]) torqueVec = np.array((self.torqueX(), self.torqueY(), self.torqueZ())) rawAngAccelVec = sp.degreesPerRadian * invInertMat @ torqueVec self.angAccelX.set(rawAngAccelVec[0]) self.angAccelY.set(rawAngAccelVec[1]) self.angAccelZ.set(rawAngAccelVec[2]) self.angVelocX.set(self.angVelocX + self.angAccelX * sp.world.period) self.angVelocY.set(self.angVelocY + self.angAccelY * sp.world.period) self.angVelocZ.set(self.angVelocZ + self.angAccelZ * sp.world.period) angVelocVec = sp.radiansPerDegree * np.array( (self.angVelocX(), self.angVelocY(), self.angVelocZ())) # Actual integration over one timestep # Source: Friendly F# and C++ (fun with game physics), by Dr Giuseppe Maggiore and Dino Dini, May 22, 2014 if cm.useQuaternions: # Quaternions are much more numerically stable self._shipRotQuat = sp.normized( self._shipRotQuat + sp.quatMul(sp.quatFromVec(angVelocVec), self._shipRotQuat) / 2 * sp.world.period()) self.shipRotQuat0.set(self._shipRotQuat[0]) self.shipRotQuat1.set(self._shipRotQuat[1]) self.shipRotQuat2.set(self._shipRotQuat[2]) self.shipRotQuat3.set(self._shipRotQuat[3]) self._shipRotQuat[0] = self.shipRotQuat0() self._shipRotQuat[1] = self.shipRotQuat1() self._shipRotQuat[2] = self.shipRotQuat2() self._shipRotQuat[3] = self.shipRotQuat3() self._shipRotMat = sp.rotMatFromQuat(self._shipRotQuat) else: # N.B. The rotation matrix cannot be found by applying angular velocity in x, y and z direction successively self._shipRotMat = self._shipRotMat + np.cross( angVelocVec, self._shipRotMat, axisb=0, axisc=0) * sp.world.period() if cm.useGramSchmidt: tf.modifiedGramSchmidt(self._shipRotMat) rawAttitudeVec = tf.getXyzAngles(self._shipRotMat) self.attitudeX.set(rawAttitudeVec[0]) self.attitudeY.set(rawAttitudeVec[1]) self.attitudeZ.set(rawAttitudeVec[2]) self.part('sweep time measurement') self.sweepMin.set(sp.world.period, sp.world.period < self.sweepMin) self.sweepMax.set(sp.world.period, sp.world.period > self.sweepMax) self.sweepWatch.reset(self.sweepWatch > 2) self.sweepMin.set(1000, not self.sweepWatch)
def sweep(self): self.part('torso') self.torAngDif.set(self.torAngSet - self.torAng) self.torRound.mark(sp.abs(self.torAngDif) < self.torMarg) self.torSpeedSet.set( sp.limit(self.torSpeedFac * self.torAngDif, self.torSpeedMax)) self.torSpeed.set((self.torAng - self.torAngOld) / sp.world.period) self.torSpeedDif.set(self.torSpeedSet - self.torSpeed) self.torVolt.set( sp.limit(self.torVoltFac * self.torSpeedDif, self.torVoltMax)) self.torEnab.mark(self.go) self.torAngOld.set(self.torAng) self.part('upper arm') self.uppAngDif.set(self.uppAngSet - self.uppAng) self.uppRound.mark(sp.abs(self.uppAngDif) < self.uppMarg) self.uppSpeedSet.set( sp.limit(self.uppSpeedFac * self.uppAngDif, self.uppSpeedMax)) self.uppSpeed.set((self.uppAng - self.uppAngOld) / sp.world.period) self.uppSpeedDif.set(self.uppSpeedSet - self.uppSpeed) self.uppVolt.set( sp.limit(self.uppVoltFac * self.uppSpeedDif, self.uppVoltMax)) self.uppEnab.mark(self.go and self.torRound) self.uppAngOld.set(self.uppAng) self.part('fore arm') self.forAngDif.set(self.forAngSet - self.forAng) self.forRound.mark(sp.abs(self.forAngDif) < self.forMarg) self.forSpeedSet.set( sp.limit(self.forSpeedFac * self.forAngDif, self.forSpeedMax)) self.forSpeed.set((self.forAng - self.forAngOld) / sp.world.period) self.forSpeedDif.set(self.forSpeedSet - self.forSpeed) self.forVolt.set( sp.limit(self.forVoltFac * self.forSpeedDif, self.forVoltMax)) self.forEnab.mark(self.go and self.torRound and self.uppRound) self.forAngOld.set(self.forAng) self.part('wrist') self.wriAngDif.set(self.wriAngSet - self.wriAng) self.wriRound.mark(sp.abs(self.wriAngDif) < self.wriMarg) self.wriSpeedSet.set( sp.limit(self.wriSpeedFac * self.wriAngDif, self.wriSpeedMax)) self.wriSpeed.set((self.wriAng - self.wriAngOld) / sp.world.period) self.wriSpeedDif.set(self.wriSpeedSet - self.wriSpeed) self.wriVolt.set( sp.limit(self.wriVoltFac * self.wriSpeedDif, self.wriVoltMax)) self.wriEnab.mark(self.go and self.torRound and self.uppRound and self.forRound) self.wriAngOld.set(self.wriAng) self.part('hand and fingers') self.hanEnab.mark(self.go and self.torRound and self.uppRound and self.forRound and self.wriRound) self.finTimer.reset(not self.hanEnab) self.finEnab.mark(self.finTimer > self.finDelay) self.finLatch.latch(self.finTimer > 0.01) self.part('sweep time measurement') self.sweepMin.set(sp.world.period, sp.world.period < self.sweepMin) self.sweepMax.set(sp.world.period, sp.world.period > self.sweepMax) self.sweepWatch.reset(self.sweepWatch > 2) self.sweepMin.set(1000, not self.sweepWatch) self.sweepMax.set(0, not self.sweepWatch)
def sweep(self): self.part('Edge triggering of buttons') self.powerEdge.trigger(self.powerButton) self.power.mark(not self.power, not self.childLock and self.powerEdge) self.childLockChangeTimer.reset(not ( self.power and self.childLockButton)) self.childLockEdge.trigger(self.childLockChangeTimer > 5) self.childLock.mark(not self.childLock, self.childLockEdge) self.unlocked.mark(self.power and not self.childLock) self.plateSelectEdge.trigger(self.plateSelectButton) self.plateSelectDelta.set(1, self.unlocked and self.plateSelectEdge, 0) self.plateSelectNr.set( (self.plateSelectNr + self.plateSelectDelta) % 4, self.power, 0) self.upEdge.trigger(self.upButton) self.downEdge.trigger(self.downButton) self.part('Cooking alarm') self.alarmSelectEdge.trigger(self.power and self.alarmSelectButton) self.alarmSelected.mark(not self.alarmSelected, self.unlocked and self.alarmSelectEdge) self.alarmChangeTimer.reset(not ( self.alarmSelected and (self.upButton or self.downButton))) self.alarmChangeStep.set(1, self.alarmChangeTimer > 0, 0) self.alarmChangeStep.set(10, self.alarmChangeTimer > 10) self.alarmChangeStep.set(100, self.alarmChangeTimer > 20) self.alarmDelta.set(-self.alarmChangeStep, self.downButton, self.alarmChangeStep) self.alarmTime.set( 0, self.power and self.upButton and self.downButton, sp.limit(self.alarmTime + self.alarmDelta * sp.world.period, 0, 9999)) self.alarmOn.latch(self.alarmChangeTimer > 0) self.alarmTimer.reset(not self.alarmOn or self.alarmChangeTimer > 0) self.alarmEdge.trigger( self.alarmTimer > self.alarmTime or (self.childLock and (self.powerButton or self.plateSelectButton or self.alarmSelectButton or self.plateSelectButton or self.upButton or self.downButton))) self.alarmOn.unlatch(self.alarmEdge or self.alarmTime == 0) self.alarmTimeLeft.set(max((self.alarmTime - self.alarmTimer), 0)) self.part('Cooking plates') self.plate0Selected.mark(self.plateSelectNr == 0) self.plate1Selected.mark(self.plateSelectNr == 1) self.plate2Selected.mark(self.plateSelectNr == 2) self.plate3Selected.mark(self.plateSelectNr == 3) self.tempChange.mark(self.unlocked and not self.alarmSelected and (self.upEdge or self.downEdge)) self.tempDelta.set(-1, not self.alarmSelected and self.downButton, 1) self.plate0Temp.set(sp.limit(self.plate0Temp + self.tempDelta, 0, 9), self.tempChange and self.plate0Selected) self.plate1Temp.set(sp.limit(self.plate1Temp + self.tempDelta, 0, 9), self.tempChange and self.plate1Selected) self.plate2Temp.set(sp.limit(self.plate2Temp + self.tempDelta, 0, 9), self.tempChange and self.plate2Selected) self.plate3Temp.set(sp.limit(self.plate3Temp + self.tempDelta, 0, 9), self.tempChange and self.plate3Selected) self.part('Buzzer tone generation and pitch bend') self.buzzerOn.latch(self.alarmEdge) self.buzzerOnTimer.reset(not self.buzzerOn) self.buzzerOn.unlatch(self.buzzerOnTimer > self.buzzerOnTime) self.buzzerPitchTimer.reset(self.buzzerPitchTimer > 3) self.buzzerFreq.set(self.buzzerBaseFreq * (1 + self.buzzerPitchTimer)) self.buzzerWaveTimer.reset( self.buzzerWaveTimer > 0.5 / self.buzzerFreq) self.buzzerEdge.trigger(self.buzzerWaveTimer == 0) self.buzzer.mark(not self.buzzer, self.buzzerOn and self.buzzerEdge) self.part('Numerical display') self.digitIndex.set((self.digitIndex + 1) % 4) self.plateDigitValue.set(self.plate0Temp, self.digitIndex == 3) self.plateDigitValue.set(self.plate1Temp, self.digitIndex == 2) self.plateDigitValue.set(self.plate2Temp, self.digitIndex == 1) self.plateDigitValue.set(self.plate3Temp, self.digitIndex == 0) self.alarmDigitValue.set(sp.digit(self.alarmTimeLeft, self.digitIndex)) self.digitValue.set(self.alarmDigitValue, self.alarmSelected, self.plateDigitValue) self.digitDot.mark(self.plate0Selected, self.digitIndex == 3) self.digitDot.mark(self.plate1Selected, self.digitIndex == 2) self.digitDot.mark(self.plate2Selected, self.digitIndex == 1) self.digitDot.mark(self.plate3Selected, self.digitIndex == 0) self.digitDot.mark(True, self.childLock) self.digitDot.mark(False, self.alarmSelected) self.part('Sweep time measurement') self.sweepMin.set(sp.world.period, sp.world.period < self.sweepMin) self.sweepMax.set(sp.world.period, sp.world.period > self.sweepMax) self.sweepWatch.reset(self.sweepWatch > 2) self.sweepMin.set(1000, not self.sweepWatch) self.sweepMax.set(0, not self.sweepWatch)