CI Log in

zach/dotter

src/models.js 108 lines · 4.5 KB · javascript
1
// Plotter models, handling modes, and pen-lift motors (port of
2
// nextdrawcore/nextdraw_options/models.py).
3
4
// Servo PWM limits are in units of 1/12 MHz (~83.3 ns).
5
export const zMotors = [
6
  { motorName: 'Standard servo', pin: 1, max: 27831, min: 9855, sweepTime: 200, moveMin: 45, moveSlope: 2.69 },
7
  { motorName: 'Narrow-band brushless servo', pin: 2, max: 12600, min: 5400, sweepTime: 70, moveMin: 20, moveSlope: 1.28 },
8
];
9
10
// resolution 1: high (2032 steps/in per motor axis), 2: low (1016 steps/in).
11
// jerk 0 means constant-speed mode.
12
export const handlers = [
13
  { name: 'No handler selected' },
14
  { name: 'Technical drawing', resolution: 1, jerk: 20000, speed: 8.6979, speedUp: 8.6979, tolerance: 0.002 },
15
  { name: 'Handwriting', resolution: 2, jerk: 90000, speed: 7, speedUp: 12, tolerance: 0.008 },
16
  { name: 'Sketching', resolution: 2, jerk: 14000, speed: 12, speedUp: 12, tolerance: 0.005 },
17
  { name: 'Constant speed', resolution: 1, jerk: 0, speed: 3.0, speedUp: 8.6979, tolerance: 0.002 },
18
];
19
20
function plotter(modelName, travelX, travelY, jerkPenUpHi, jerkPenUpLo, jerkDerate, autoHome, zMotor) {
21
  return { modelName, travelX, travelY, jerkPenUpHi, jerkPenUpLo, jerkDerate, autoHome, zMotor };
22
}
23
24
export const plotters = [
25
  plotter('No model selected', 0, 0, 0, 0, 1, false, 1),
26
  plotter('AxiDraw V3 or SE/A4', 11.81, 8.58, 19000, 13000, 1.0, false, 0),
27
  plotter('AxiDraw V3/A3 or SE/A3', 16.93, 11.69, 17000, 12000, 0.9, false, 0),
28
  plotter('AxiDraw V3 XLX', 23.42, 8.58, 18000, 13000, 1.0, false, 0),
29
  plotter('AxiDraw MiniKit', 6.30, 4.00, 6000, 6000, 0.6, false, 0),
30
  plotter('AxiDraw SE/A1', 34.02, 23.39, 13000, 8000, 0.6, false, 0),
31
  plotter('AxiDraw SE/A2', 23.39, 17.01, 16000, 10000, 0.7, false, 0),
32
  plotter('AxiDraw V3/B6', 7.48, 5.51, 14000, 14000, 1.0, false, 0),
33
  plotter('Bantam Tools NextDraw™ 8511', 11.81, 8.58, 19000, 13000, 1.0, true, 1),
34
  plotter('Bantam Tools NextDraw™ 1117', 16.93, 11.69, 17000, 12000, 0.9, true, 1),
35
  plotter('Bantam Tools NextDraw™ 2234', 34.02, 23.39, 13000, 8000, 0.6, true, 1),
36
];
37
38
const OVERRIDE_KEYS = {
39
  modelName: 'modelName', travelX: 'travelX', travelY: 'travelY', jerkPenUp: 'jerkPenUp',
40
  autoHome: 'autoHome', resolution: 'resolution', curveTolerance: 'curveTolerance',
41
  constSpeed: 'constSpeed', jerkPenDown: 'jerkPenDown', speedLimit: 'speedLimit', zMotor: 'zMotor',
42
};
43
const SERVO_OVERRIDE_KEYS = ['servoPin', 'servoMax', 'servoMin', 'servoSweepTime', 'servoMoveMin', 'servoMoveSlope'];
44
45
/**
46
 * Apply model-, handling- and servo-specific defaults to nd.params, then any
47
 * non-null nd.params.overrides (models.apply_model_and_handling).
48
 */
49
export function applyModelAndHandling(nd, initialize = false) {
50
  const p = nd.params;
51
  if (initialize) {
52
    p.modelOld = -1;
53
    p.handlingOld = -1;
54
    p.zMotorOld = -1;
55
  }
56
  const model = nd.options.model;
57
  if (model === 0) return;
58
  if (!(model >= 1 && model < plotters.length)) throw new RangeError(`Invalid model: ${model}`);
59
60
  if (model !== p.modelOld) {
61
    p.modelOld = model;
62
    const m = plotters[model];
63
    p.modelName = m.modelName;
64
    p.travelX = m.travelX;
65
    p.travelY = m.travelY;
66
    p.jerkDerate = m.jerkDerate;
67
    p.autoHome = m.autoHome;
68
    p.zMotor = m.zMotor;
69
    if (nd.options.penlift === 3) p.zMotor = 1; // Brushless upgrade
70
    // Handling values depend on the model's jerk derating. (The Python driver
71
    // keeps the old values until the handling mode changes; we recompute.)
72
    p.handlingOld = -1;
73
  }
74
75
  const handling = nd.options.handling;
76
  if (handling !== 0 && handling !== p.handlingOld) {
77
    if (!(handling >= 1 && handling <= 4)) throw new RangeError(`Invalid handling: ${handling}`);
78
    p.handlingOld = handling;
79
    const h = handlers[handling];
80
    p.resolution = h.resolution;
81
    p.jerkPenDown = h.jerk * p.jerkDerate;
82
    p.constSpeed = h.jerk === 0;
83
    p.curveTolerance = h.tolerance;
84
    const lim = p.resolution === 2 ? p.speedLimXyLr : p.speedLimXyHr;
85
    p.speedLimit = Math.min(h.speed, lim);
86
    p.speedUp = Math.min(h.speedUp, lim);
87
  }
88
89
  p.jerkPenUp = p.resolution === 2 ? plotters[model].jerkPenUpLo : plotters[model].jerkPenUpHi;
90
91
  for (const key of Object.keys(OVERRIDE_KEYS)) {
92
    if (p.overrides[key] != null) p[key] = p.overrides[key];
93
  }
94
95
  if (p.zMotor !== p.zMotorOld) {
96
    p.zMotorOld = p.zMotor;
97
    const z = zMotors[p.zMotor];
98
    p.servoPin = z.pin;
99
    p.servoMax = z.max;
100
    p.servoMin = z.min;
101
    p.servoSweepTime = z.sweepTime;
102
    p.servoMoveMin = z.moveMin;
103
    p.servoMoveSlope = z.moveSlope;
104
  }
105
  for (const key of SERVO_OVERRIDE_KEYS) {
106
    if (p.overrides[key] != null) p[key] = p.overrides[key];
107
  }
108
}