Browse Source

Validate randomized pen settings

Kevin Lee 3 months ago
parent
commit
19aa6c19f8
2 changed files with 83 additions and 40 deletions
  1. 82 39
      src/config/pen.rs
  2. 1 1
      src/ezcad/pen.rs

+ 82 - 39
src/config/pen.rs

@@ -106,7 +106,7 @@ impl PatchPen {
         debug!("Patching pen #{}", self.pen);
         let pen: &mut Pen = pens.get_mut(self.pen).expect("Invalid pen index");
         self.patch.patch(pen);
-        pen.check_settings();
+        pen.valid_settings();
     }
 }
 
@@ -292,7 +292,7 @@ impl PatternField {
             // Always enable custom settings for pen
             *dst.use_default = 0;
 
-            dst.check_settings();
+            dst.valid_settings();
         }
     }
 }
@@ -322,6 +322,30 @@ impl PatternPen {
     }
 }
 
+#[derive(Copy, Clone, Default, PartialEq)]
+struct RandomizedSetting {
+    speed: Option<f64>,
+    power: Option<f64>,
+    frequency: Option<u32>,
+    pulse_width: Option<PulseWidth>,
+}
+
+impl RandomizedSetting {
+    fn apply(&self, pen: &mut Pen) {
+        self.speed.map(|speed| *pen.speed = speed);
+        self.power.map(|power| *pen.power = power);
+        self.frequency.map(|freq| {
+            *pen.frequency = freq;
+            *pen.frequency_2 = freq.try_into().unwrap();
+        });
+        self.pulse_width.map(|pw| {
+            let pw: u32 = pw.into();
+            *pen.pulse_width = pw;
+            *pen.pulse_width_2 = pw.try_into().unwrap();
+        });
+    }
+}
+
 #[derive(Debug, Serialize, Deserialize)]
 #[serde(rename_all = "PascalCase")]
 pub struct RandomizePen {
@@ -341,55 +365,74 @@ impl RandomizePen {
             self.index + self.count - 1
         );
 
+        let mut generated: Vec<RandomizedSetting> = vec![];
+
         for (index, pen) in pens
             .iter_mut()
             .skip(self.index)
             .take(self.count)
             .enumerate()
         {
-            if let Some((min, max, step)) = self.speed {
-                let offset: usize = rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
-                let value: f64 = min + step * offset as f64;
-                debug!("Randomizing speed for pen #{} to {}", index, value);
-                *pen.speed = value;
-            }
+            loop {
+                let mut setting: RandomizedSetting = RandomizedSetting::default();
+
+                if let Some((min, max, step)) = self.speed {
+                    let offset: usize =
+                        rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
+                    let value: f64 = min + step * offset as f64;
+                    debug!("Randomizing speed for pen #{} to {}", index, value);
+                    setting.speed = Some(value);
+                }
 
-            if let Some((min, max, step)) = self.power {
-                let offset: usize = rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
-                let value: f64 = min + step * offset as f64;
-                debug!("Randomizing power for pen #{} to {}", index, value);
-                *pen.power = value;
-            }
+                if let Some((min, max, step)) = self.power {
+                    let offset: usize =
+                        rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
+                    let value: f64 = min + step * offset as f64;
+                    debug!("Randomizing power for pen #{} to {}", index, value);
+                    setting.power = Some(value);
+                }
 
-            if let Some((min, max, step)) = self.frequency {
-                let offset: usize = rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
-                let value: u32 = min + step * offset as u32;
-                debug!("Randomizing frequency for pen #{} to {}", index, value);
-                *pen.frequency = value;
-                *pen.frequency_2 = value.try_into().unwrap();
-            }
+                if let Some((min, max, step)) = self.frequency {
+                    let offset: usize =
+                        rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
+                    let value: u32 = min + step * offset as u32;
+                    debug!("Randomizing frequency for pen #{} to {}", index, value);
+                    setting.frequency = Some(value);
+                }
 
-            if let Some((min, max, step)) = self.pulse_width {
-                let mut pw = PulseWidth::iter();
-                let mut values: Vec<PulseWidth> = vec![pw.find(|x| *x == min).unwrap()];
-                values.extend(
-                    pw.skip(step - 1)
-                        .step_by(step)
-                        .take_while_inclusive(|x| *x != max)
-                        .collect_vec(),
-                );
+                if let Some((min, max, step)) = self.pulse_width {
+                    let mut pw = PulseWidth::iter();
+                    let mut values: Vec<PulseWidth> = vec![pw.find(|x| *x == min).unwrap()];
+                    values.extend(
+                        pw.skip(step - 1)
+                            .step_by(step)
+                            .take_while_inclusive(|x| *x != max)
+                            .collect_vec(),
+                    );
 
-                let width: &PulseWidth = values
-                    .choose_multiple(&mut rand::thread_rng(), 1)
-                    .next()
-                    .unwrap();
-                let value: u32 = (*width).into();
-                debug!("Randomizing pulse width for pen #{} to {}", index, value);
-                *pen.pulse_width = value;
-                *pen.pulse_width_2 = value.try_into().unwrap();
+                    let width: &PulseWidth = values
+                        .choose_multiple(&mut rand::thread_rng(), 1)
+                        .next()
+                        .unwrap();
+                    let value: u32 = (*width).into();
+                    debug!("Randomizing pulse width for pen #{} to {}", index, value);
+                    setting.pulse_width = Some(*width);
+                }
+
+                if !generated.contains(&setting) {
+                    generated.push(setting);
+                    setting.apply(pen);
+                    if !pen.valid_settings() {
+                        debug!("Retrying..");
+                    } else {
+                        break;
+                    }
+                } else {
+                    debug!("Duplicate random setting");
+                }
             }
 
-            pen.check_settings();
+            pen.valid_settings();
         }
     }
 }

+ 1 - 1
src/ezcad/pen.rs

@@ -122,7 +122,7 @@ impl Pen {
             .expect("Failed to write to output file");
     }
 
-    pub fn check_settings(&self) -> bool {
+    pub fn valid_settings(&self) -> bool {
         let mut ret: bool = true;
 
         if *self.frequency != *self.frequency_2 as u32 {