diff options
| author | Selene ToyKeeper | 2021-08-12 03:05:11 -0600 |
|---|---|---|
| committer | Selene ToyKeeper | 2021-08-12 03:05:11 -0600 |
| commit | 3a6ff5816deb38b109b1550f800f9096e99d4cac (patch) | |
| tree | 7055780e71e44d428f380e2bbc23663f8e95a5c1 /bin | |
| parent | added a "jump start moon" option for hold-from-off, for lights with slow-acti... (diff) | |
| download | anduril-3a6ff5816deb38b109b1550f800f9096e99d4cac.tar.gz anduril-3a6ff5816deb38b109b1550f800f9096e99d4cac.tar.bz2 anduril-3a6ff5816deb38b109b1550f800f9096e99d4cac.zip | |
made PWM TOP value configurable at command line in level_calc.py, and added a "dynamic PWM" feature
(uses a different PWM TOP at each of the first N ramp levels,
to increase resolution at bottom end of ramp)
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/level_calc.py | 79 |
1 files changed, 70 insertions, 9 deletions
diff --git a/bin/level_calc.py b/bin/level_calc.py index a780405..e194331 100755 --- a/bin/level_calc.py +++ b/bin/level_calc.py @@ -9,11 +9,29 @@ interactive = False #ramp_shape = 'cube' max_pwm = 255 +max_pwms = [] +dyn_pwm = False def main(args): """Calculates PWM levels for visually-linear steps. """ + pwm_arg = str(max_pwm) + cli_answers = [] + global max_pwm, max_pwms, dyn_pwm + + i = 0 + while i < len(args): + a = args[i] + if a in ('--pwm',): + i += 1 + pwm_arg = args[i] + else: + #print('unrecognized option: "%s"' % (a,)) + cli_answers.append(a) + + i += 1 + # Get parameters from the user questions_main = [ (str, 'ramp_shape', 'cube', 'Ramp shape? [cube, square, fifth, seventh, ninth, log, N.NN]'), @@ -30,7 +48,7 @@ def main(args): def ask(questions, ans): for typ, name, default, text in questions: - value = get_value(text, default, args) + value = get_value(text, default, cli_answers) if not value: value = default else: @@ -40,14 +58,33 @@ def main(args): answers = Empty() ask(questions_main, answers) - global ramp_shape + if pwm_arg: + if pwm_arg.startswith('dyn:'): + dyn_pwm = True + parts = pwm_arg.split(':') + dpwm_steps = int(parts[1]) + dpwn_max = int(parts[2]) + dpwn_min = int(parts[3]) + max_pwms = [dpwn_min] * answers.num_levels + for i in range(dpwm_steps): + span = dpwn_max - dpwn_min + x = dpwn_min + (span * (float(dpwm_steps - i) / dpwm_steps)) + max_pwms[i] = int(x) + max_pwm = dpwn_min + + else: + val = int(pwm_arg) + max_pwm = val + max_pwms = [val] * answers.num_levels + + global ramp_shape ramp_shape = answers.ramp_shape channels = [] - if not args: + if not answers: print('Describe the channels in order of lowest to highest power.') for chan_num in range(answers.num_channels): - if not args: + if not answers: print('===== Channel %s =====' % (chan_num+1)) chan = Empty() chan.pwm_max = max_pwm @@ -119,7 +156,7 @@ def multi_pwm(answers, channels): channel.modes.append(0.0) # Normal non-turbo mode or non-FET turbo else: - channel.modes.append(channel.pwm_max) + channel.modes.append(max_pwms[i]) # This channel's active ramp-up range #elif goal_lm > (channel.prev_lm + channel.lm_min): elif goal_lm > channel.prev_lm: @@ -132,7 +169,27 @@ def multi_pwm(answers, channels): needed = goal_lm - channel.prev_lm - channel.lm_min - ratio = needed / diff * (channel.pwm_max-channel.pwm_min) + ceil = max_pwms[i] + ratio = needed / diff * (ceil-channel.pwm_min) + # if there's wiggle room, adjust ceiling to reduce error + #if dyn_pwm: + # this_step = max(1, math.floor(ratio)) + # next_step = this_step + 0.5 + # limit = float(this_step) / next_step * ceil + # limit = max(limit, max_pwm) + #while (ceil > limit) and ((ratio - math.floor(ratio)) > 0.1): + # ceil -= 1 + # ratio = needed / diff * (ceil-channel.pwm_min) + # max_pwms[i] = ceil + if dyn_pwm and (ceil > max_pwm): + this_step = max(1, math.floor(ratio)) + next_step = this_step + 1 + fpart = ratio - math.floor(ratio) + correction = (next_step - fpart) / next_step + ceil = int(ceil * correction) + ratio = needed / diff * (ceil-channel.pwm_min) + max_pwms[i] = ceil + # save the result pwm = max(0, ratio + channel.pwm_min) channel.modes.append(pwm) # This channel isn't active yet, output too low @@ -144,7 +201,7 @@ def multi_pwm(answers, channels): goal_vis, goal_lm = goals[i] pwms = [] for channel in channels: - pwms.append('%.2f/%i' % (channel.modes[i], channel.pwm_max)) + pwms.append('%.2f/%i' % (channel.modes[i], max_pwms[i])) print('%i: visually %.2f (%.2f lm): %s' % (i+1, goal_vis, goal_lm, ', '.join(pwms))) @@ -154,15 +211,19 @@ def multi_pwm(answers, channels): (cnum+1, ','.join([str(int(round(i))) for i in channel.modes]))) + # Show PFM values (PWM TOP) + if dyn_pwm: + print('PWM_TOP: %s' % (','.join(str(x) for x in max_pwms))) + # Show highest level for each channel before next channel starts for cnum, channel in enumerate(channels[:-1]): prev = 0 i = 1 while (i < answers.num_levels) \ - and (channel.modes[i] >= channel.modes[i-1]) \ and (channels[cnum+1].modes[i] == 0): + #and (channel.modes[i] >= channel.modes[i-1]) \ i += 1 - print('Ch%i max: %i (%.2f/%s)' % (cnum, i, channel.modes[i-1], max_pwm)) + print('Ch%i max: %i (%.2f/%s)' % (cnum, i, channel.modes[i-1], max_pwms[i])) def get_value(text, default, args): |
