wavemeter: new algo

This commit is contained in:
Sebastien Bourdeauducq 2019-11-04 18:59:14 +08:00
parent 110a5d2990
commit 67368ae352
2 changed files with 66 additions and 7 deletions

View File

@ -35,6 +35,9 @@ struct Config {
refpll_kp: i64, // Proportionality constant of the DPLL loop filter. refpll_kp: i64, // Proportionality constant of the DPLL loop filter.
ref_wavelength: f64, // Wavelength of the reference laser in m. ref_wavelength: f64, // Wavelength of the reference laser in m.
position_mon_time: f64, // The time during which position is monitored to compute min/max
duty_cycle: f64 // Fraction of the scan used for counting input laser fringes
} }
fn read_config_from_file<P: AsRef<Path>>(path: P) -> Result<Config, Box<dyn Error>> { fn read_config_from_file<P: AsRef<Path>>(path: P) -> Result<Config, Box<dyn Error>> {
@ -47,7 +50,7 @@ fn read_config_from_file<P: AsRef<Path>>(path: P) -> Result<Config, Box<dyn Erro
fn do_calibrate(config: &Config) { fn do_calibrate(config: &Config) {
let mut sample_count = 0; let mut sample_count = 0;
let avg_ref = (config.ref_min + config.ref_max)/2.0; let avg_ref = (config.ref_min + config.ref_max)/2.0;
let max_sample_count = (avg_ref/4.0) as u32; let max_sample_count = (avg_ref*config.position_mon_time) as u32;
let mut position_min = i64::max_value(); let mut position_min = i64::max_value();
let mut position_max = i64::min_value(); let mut position_max = i64::min_value();
@ -125,19 +128,72 @@ fn do_wavemeter(config: &Config) {
let mut position_tracker = noptica::PositionTracker::new(); let mut position_tracker = noptica::PositionTracker::new();
let mut motion_tracker = MotionTracker::new(); let mut motion_tracker = MotionTracker::new();
let mut position_min = i64::max_value();
let mut position_max = i64::min_value();
let avg_ref = (config.ref_min + config.ref_max)/2.0;
let max_position_sample_count = (avg_ref*config.position_mon_time) as u32;
let mut position_sample_count = 0;
let mut duty_min = i64::max_value();
let mut duty_max = i64::min_value();
let mut prev_in_duty = false;
let mut first_fringe = 0;
let mut fringe_count = 0;
noptica::sample(&config.sample_command, |rising, _falling| { noptica::sample(&config.sample_command, |rising, _falling| {
refpll.tick(rising & (1 << config.bit_ref) != 0); refpll.tick(rising & (1 << config.bit_ref) != 0);
if refpll.locked() { if refpll.locked() {
let position = if rising & (1 << config.bit_meas) != 0 { let position_opt;
Some(position_tracker.edge(refpll.get_phase_unwrapped())) if rising & (1 << config.bit_meas) != 0 {
let position = position_tracker.edge(refpll.get_phase_unwrapped());
if position > position_max {
position_max = position;
}
if position < position_min {
position_min = position;
}
position_sample_count += 1;
if position_sample_count == max_position_sample_count {
let amplitude = position_max - position_min;
let off_duty = ((amplitude as f64)*(1.0 - config.duty_cycle)) as i64;
duty_min = position_min + off_duty/2;
duty_max = position_max - off_duty/2;
position_sample_count = 0;
}
position_opt = Some(position);
} else { } else {
None position_opt = None
}; };
motion_tracker.tick(position); motion_tracker.tick(position_opt);
if rising & (1 << config.bit_input) != 0 { if rising & (1 << config.bit_input) != 0 {
let fringe_position = motion_tracker.extrapolated_position(); let fringe_position = motion_tracker.extrapolated_position();
println!("{}", (fringe_position as f64)/(noptica::Dpll::TURN as f64)); let in_duty = (duty_min < fringe_position) && (fringe_position < duty_max);
if in_duty & !prev_in_duty {
first_fringe = fringe_position;
fringe_count = 0;
}
if !in_duty & prev_in_duty {
let wavelength = (fringe_position - first_fringe).abs()/fringe_count;
let max_displacement = ((position_max-position_min) as f64)/(noptica::Dpll::TURN as f64)*config.ref_wavelength;
let displacement = ((fringe_position - first_fringe).abs() as f64)/(noptica::Dpll::TURN as f64)*config.ref_wavelength;
println!("{:.4} {} {:.2} {} {:.1}",
(wavelength as f64)/(noptica::Dpll::TURN as f64)*1.0e9*config.ref_wavelength,
fringe_count,
1.0e6*max_displacement,
if fringe_position > first_fringe { "UP " } else { "DOWN" },
1.0e9*displacement);
fringe_count = 0;
}
fringe_count += 1;
prev_in_duty = in_duty;
} }
} else {
position_min = i64::max_value();
position_max = i64::min_value();
position_sample_count = 0;
duty_min = i64::max_value();
duty_max = i64::min_value();
prev_in_duty = false;
} }
}) })
} }

View File

@ -10,5 +10,8 @@
"refpll_ki": 4294967, "refpll_ki": 4294967,
"refpll_kp": 85899345, "refpll_kp": 85899345,
"ref_wavelength": 632.991372e-9 "ref_wavelength": 632.991372e-9,
"position_mon_time": 0.25,
"duty_cycle": 0.5
} }