def render(self, dmx_univ): """Render this Comet into a DMX universe.""" start = self.dmx_addr # render the shutter value dmx_univ[start:start+2] = self._render_ball_rotation() dmx_univ[start+2] = self._render_color_rotation() dmx_univ[start+3:start+5] = _render_strobe( self.strobe_1_state, self.strobe_1_intensity, self.strobe_1_rate) dmx_univ[start+5:start+7] = _render_strobe( self.strobe_2_state, self.strobe_2_intensity, self.strobe_2_rate) dmx_univ[start+7] = unit_float_to_range(0, 255, self.lamp_1_intensity) dmx_univ[start+8] = unit_float_to_range(0, 255, self.lamp_2_intensity) log.info(dmx_univ[start:start+9])
def _render_white_led_state(self): if not self.white_leds_on: return 0 else: program_offset = 10 * (self.white_led_program + 1) speed_offset = unit_float_to_range(0, 9, self.white_led_speed) return program_offset + speed_offset
def _render_white_led_state(self): if not self.white_leds_on: return 0 else: program_offset = 10*(self.white_led_program+1) speed_offset = unit_float_to_range(0, 9, self.white_led_speed) return program_offset + speed_offset
def render(self, dmx_univ): """Render the Venus into a DMX universe.""" dmx_addr = self.dmx_addr base_dir, base_val = bipolar_to_dir_and_val(self.base_rotation.current) cradle_val = unit_float_to_range(0, 255, self.cradle_motion.current) head_dir, head_val = bipolar_to_dir_and_val(self.head_rotation.current) # limit color wheel speed to 50% for the time being col_dir, col_val = bipolar_to_dir_and_val( 0.5 * self.color_rotation.current) lamp_val = 255 if self.lamp_on else 0 vals = ( base_dir, base_val, cradle_val, head_dir, head_val, col_dir, col_val, lamp_val) #logging.debug("{}".format(vals)) for offset, val in enumerate(vals): dmx_univ[dmx_addr+offset] = val
def _render_ball_rotation(self): val = self.ball_rotation.current speed = abs(val) direction = val >= 0.0 if self.ball_start and speed < 0.2: speed = 0.2 dmx_speed = unit_float_to_range(0, 255, speed) dmx_direction = 0 if direction else 255 return dmx_speed, dmx_direction
def _render_ball_rotation(self): val = self.ball_rotation.current speed = abs(val) direction = val >= 0.0 if self.ball_start and speed < 0.2: speed = 0.2 dmx_speed = unit_float_to_range(0, MAX_ROTATION_SPEED, speed) dmx_direction = 0 if direction else 255 return dmx_speed, dmx_direction
def _render_shutter(self): """Render the shutter state into DMX.""" if not self.shutter_open: return 0 elif self.shutter_sound_active: return 125 elif self.strobing: return unit_float_to_range(151, 255, self.strobe_rate) else: return 75
def _update(self): """Update the DMX trigger state value. This is a fairly complex action, as the step interface at the DMX level is kinda hokey. I give top priority to the mechanism by which we achieve manual stepping. After that, music responsive mode. After that, automatic stepping. The trigger UI should make it clear that music trigger and auto trigger are mutually exclusive options. """ # what needs to happen to take a step: # the dmx value needs to go from its current state to the step value # if the current value is the step value, we need to leave and come back again if self.steps_to_take: next_step = self.steps_to_take[-1] # hold this output for a minimum frame count before processing next self.updates_to_hold += self._updates_to_hold - 1 if next_step == Forward and self.prior_state != SteppingForwards: # can take this step, transition to forward self.prior_state = SteppingForwards self.steps_to_take.pop() return self._step_forward_dmx_val elif next_step == Backward and self.prior_state != SteppingBackwards: # can take this step, transition to backward self.prior_state = SteppingBackwards self.steps_to_take.pop() return self._step_backward_dmx_val else: # we're in the same state as the step we need to take # transition to Idle, then take the step on the next update self.prior_state = Idle return self._stop_dmx_val # nothing in the step queue so the state machine is idle self.prior_state = Idle # if we're not taking a step, easy sauce if self.music_trigger: return self._music_dmx_val elif self.auto_step: return unit_float_to_range(151, 255, self.auto_step_rate) else: return self._stop_dmx_val
def render_trigger(self): """Render the trigger state to DMX. This is a fairly complex action, as the step interface at the DMX level is kinda hokey. I give top priority to the mechanism by which we achieve manual stepping. After that, music responsive mode. After that, automatic stepping. The trigger UI should make it clear that music trigger and auto trigger are mutually exclusive options. """ # what needs to happen to take a step: # the dmx value needs to go from its current state to the step value # if the current value is the step value, we need to leave and come back again # yikes! # first check to see if we need to take a step: last_state = self._state if self._take_a_step: targ_state = StepForwards if self._direction is Forwards else StepBackwards # if our last state was a different state, no problem if last_state != targ_state: self._take_a_step = False self._busy = False if self._direction is Forwards: self._state = StepForwards return self._step_f_dmx_val else: self._state = StepBackwards return self._step_b_dmx_val # otherwise, we need to take an intermediate step to the "stopped" # state and THEN to the step state self._busy = True self._state = Idle return self._stop_dmx_val # if we're not taking a step, easy sauce elif self.music_trigger: return self._music_dmx_val elif self.auto_step: return unit_float_to_range(151, 255, self.auto_step_rate) else: return self._stop_dmx_val
def render(self, dmx_univ): """Render the Venus into a DMX universe.""" dmx_addr = self.dmx_addr base_dir, base_val = bipolar_to_dir_and_val(self.base_rotation.current) cradle_val = unit_float_to_range(0, 255, self.cradle_motion.current) head_dir, head_val = bipolar_to_dir_and_val(self.head_rotation.current) # limit color wheel speed to 50% for the time being col_dir, col_val = bipolar_to_dir_and_val(0.5 * self.color_rotation.current) lamp_val = 255 if self.lamp_on else 0 vals = (base_dir, base_val, cradle_val, head_dir, head_val, col_dir, col_val, lamp_val) #logging.debug("{}".format(vals)) for offset, val in enumerate(vals): dmx_univ[dmx_addr + offset] = val
def bipolar_to_motor_speed(value): """Convert a bipolar float to swarmolon motor speed.""" if value < 0.0: return unit_float_to_range(128, 5, abs(value)) else: return unit_float_to_range(130, 255, value)
def _render_color_rotation(self): if self.color_start and self.color_rotation < 0.2: speed = 0.2 else: speed = self.color_rotation return unit_float_to_range(0, 255, speed)
def _render_strobe(state, intensity, rate): if state: return unit_float_to_range(0, 255, intensity), unit_float_to_range(0, 255, rate) else: return (0, 0)
def bipolar_to_dir_and_val(bipolar_val): if bipolar_val < 0.0: return 0, unit_float_to_range(0, 255, abs(bipolar_val)) else: return 255, unit_float_to_range(0, 255, bipolar_val)
def _render_mspeed(self): return unit_float_to_range(0, 255, self.mirror_speed)