|
@@ -104,14 +104,12 @@
|
104
|
104
|
|
105
|
105
|
namespace ExtUI {
|
106
|
106
|
static struct {
|
107
|
|
- uint8_t printer_killed : 1;
|
108
|
|
- uint8_t manual_motion : 1;
|
|
107
|
+ uint8_t printer_killed : 1;
|
|
108
|
+ #if ENABLED(JOYSTICK)
|
|
109
|
+ uint8_t jogging : 1;
|
|
110
|
+ #endif
|
109
|
111
|
} flags;
|
110
|
112
|
|
111
|
|
- #if ENABLED(JOYSTICK)
|
112
|
|
- float norm_jog[XYZ];
|
113
|
|
- #endif
|
114
|
|
-
|
115
|
113
|
#ifdef __SAM3X8E__
|
116
|
114
|
/**
|
117
|
115
|
* Implement a special millis() to allow time measurement
|
|
@@ -197,13 +195,45 @@ namespace ExtUI {
|
197
|
195
|
#endif
|
198
|
196
|
}
|
199
|
197
|
|
200
|
|
- void jog(float dx, float dy, float dz) {
|
201
|
|
- #if ENABLED(JOYSTICK)
|
202
|
|
- norm_jog[X] = dx;
|
203
|
|
- norm_jog[Y] = dy;
|
204
|
|
- norm_jog[Z] = dz;
|
205
|
|
- #endif
|
206
|
|
- }
|
|
198
|
+ #if ENABLED(JOYSTICK)
|
|
199
|
+ /**
|
|
200
|
+ * Jogs in the direction given by the vector (dx, dy, dz).
|
|
201
|
+ * The values range from -1 to 1 mapping to the maximum
|
|
202
|
+ * feedrate for an axis.
|
|
203
|
+ *
|
|
204
|
+ * The axis will continue to jog until this function is
|
|
205
|
+ * called with all zeros.
|
|
206
|
+ */
|
|
207
|
+ void jog(float dx, float dy, float dz) {
|
|
208
|
+ // The "destination" variable is used as a scratchpad in
|
|
209
|
+ // Marlin by GCODE routines, but should remain untouched
|
|
210
|
+ // during manual jogging, allowing us to reuse the space
|
|
211
|
+ // for our direction vector.
|
|
212
|
+ destination[X] = dx;
|
|
213
|
+ destination[Y] = dy;
|
|
214
|
+ destination[Z] = dz;
|
|
215
|
+ flags.jogging = !NEAR_ZERO(dx) || !NEAR_ZERO(dy) || !NEAR_ZERO(dz);
|
|
216
|
+ }
|
|
217
|
+
|
|
218
|
+ // Called by the polling routine in "joystick.cpp"
|
|
219
|
+ void _joystick_update(float (&norm_jog)[XYZ]) {
|
|
220
|
+ if (flags.jogging) {
|
|
221
|
+ #define OUT_OF_RANGE(VALUE) (VALUE < -1.0f || VALUE > 1.0f)
|
|
222
|
+
|
|
223
|
+ if (OUT_OF_RANGE(destination[X_AXIS]) || OUT_OF_RANGE(destination[Y_AXIS]) || OUT_OF_RANGE(destination[Z_AXIS])) {
|
|
224
|
+ // If destination[] on any axis is out of range, it
|
|
225
|
+ // probably means the UI forgot to stop jogging and
|
|
226
|
+ // ran GCODE that wrote a position to destination[].
|
|
227
|
+ // To prevent a disaster, stop jogging.
|
|
228
|
+ flags.jogging = false;
|
|
229
|
+ return;
|
|
230
|
+ }
|
|
231
|
+ norm_jog[X_AXIS] = destination[X_AXIS];
|
|
232
|
+ norm_jog[Y_AXIS] = destination[Y_AXIS];
|
|
233
|
+ norm_jog[Z_AXIS] = destination[Z_AXIS];
|
|
234
|
+ }
|
|
235
|
+ }
|
|
236
|
+ #endif
|
207
|
237
|
|
208
|
238
|
bool isHeaterIdle(const extruder_t extruder) {
|
209
|
239
|
return false
|
|
@@ -288,13 +318,22 @@ namespace ExtUI {
|
288
|
318
|
}
|
289
|
319
|
|
290
|
320
|
float getAxisPosition_mm(const axis_t axis) {
|
291
|
|
- return flags.manual_motion ? destination[axis] : current_position[axis];
|
|
321
|
+ return
|
|
322
|
+ #if ENABLED(JOYSTICK)
|
|
323
|
+ flags.jogging ? destination[axis] :
|
|
324
|
+ #endif
|
|
325
|
+ current_position[axis];
|
292
|
326
|
}
|
293
|
327
|
|
294
|
328
|
float getAxisPosition_mm(const extruder_t extruder) {
|
295
|
329
|
const extruder_t old_tool = getActiveTool();
|
296
|
330
|
setActiveTool(extruder, true);
|
297
|
|
- const float pos = flags.manual_motion ? destination[E_AXIS] : current_position[E_AXIS];
|
|
331
|
+ const float pos = (
|
|
332
|
+ #if ENABLED(JOYSTICK)
|
|
333
|
+ flags.jogging ? destination[E_AXIS] :
|
|
334
|
+ #endif
|
|
335
|
+ current_position[E_AXIS]
|
|
336
|
+ );
|
298
|
337
|
setActiveTool(old_tool, true);
|
299
|
338
|
return pos;
|
300
|
339
|
}
|
|
@@ -343,54 +382,23 @@ namespace ExtUI {
|
343
|
382
|
}
|
344
|
383
|
#endif
|
345
|
384
|
|
346
|
|
- constexpr float max_manual_feedrate[XYZE] = MANUAL_FEEDRATE;
|
347
|
|
- setFeedrate_mm_s(MMM_TO_MMS(max_manual_feedrate[axis]));
|
|
385
|
+ constexpr float manual_feedrate[XYZE] = MANUAL_FEEDRATE;
|
|
386
|
+ setFeedrate_mm_s(MMM_TO_MMS(manual_feedrate[axis]));
|
348
|
387
|
|
349
|
|
- if (!flags.manual_motion) set_destination_from_current();
|
|
388
|
+ set_destination_from_current();
|
350
|
389
|
destination[axis] = constrain(position, min, max);
|
351
|
|
- flags.manual_motion = true;
|
|
390
|
+ prepare_move_to_destination();
|
352
|
391
|
}
|
353
|
392
|
|
354
|
393
|
void setAxisPosition_mm(const float position, const extruder_t extruder) {
|
355
|
394
|
setActiveTool(extruder, true);
|
356
|
395
|
|
357
|
|
- constexpr float max_manual_feedrate[XYZE] = MANUAL_FEEDRATE;
|
358
|
|
- setFeedrate_mm_s(MMM_TO_MMS(max_manual_feedrate[E_AXIS]));
|
359
|
|
- if (!flags.manual_motion) set_destination_from_current();
|
360
|
|
- destination[E_AXIS] = position;
|
361
|
|
- flags.manual_motion = true;
|
362
|
|
- }
|
|
396
|
+ constexpr float manual_feedrate[XYZE] = MANUAL_FEEDRATE;
|
|
397
|
+ setFeedrate_mm_s(MMM_TO_MMS(manual_feedrate[E_AXIS]));
|
363
|
398
|
|
364
|
|
- void _processManualMoveToDestination() {
|
365
|
|
- // Lower max_response_lag makes controls more responsive, but makes CPU work harder
|
366
|
|
- constexpr float max_response_lag = 0.1; // seconds
|
367
|
|
- constexpr uint8_t segments_to_buffer = 4; // keep planner filled with this many segments
|
368
|
|
-
|
369
|
|
- if (flags.manual_motion && planner.movesplanned() < segments_to_buffer) {
|
370
|
|
- float saved_destination[XYZ];
|
371
|
|
- COPY(saved_destination, destination);
|
372
|
|
- // Compute direction vector from current_position towards destination.
|
373
|
|
- destination[X_AXIS] -= current_position[X_AXIS];
|
374
|
|
- destination[Y_AXIS] -= current_position[Y_AXIS];
|
375
|
|
- destination[Z_AXIS] -= current_position[Z_AXIS];
|
376
|
|
- const float inv_length = RSQRT(sq(destination[X_AXIS]) + sq(destination[Y_AXIS]) + sq(destination[Z_AXIS]));
|
377
|
|
- // Find move segment length so that all segments can execute in less time than max_response_lag
|
378
|
|
- const float scale = inv_length * feedrate_mm_s * max_response_lag / segments_to_buffer;
|
379
|
|
- if (scale < 1) {
|
380
|
|
- // Move a small bit towards the destination.
|
381
|
|
- destination[X_AXIS] = scale * destination[X_AXIS] + current_position[X_AXIS];
|
382
|
|
- destination[Y_AXIS] = scale * destination[Y_AXIS] + current_position[Y_AXIS];
|
383
|
|
- destination[Z_AXIS] = scale * destination[Z_AXIS] + current_position[Z_AXIS];
|
384
|
|
- prepare_move_to_destination();
|
385
|
|
- COPY(destination, saved_destination);
|
386
|
|
- }
|
387
|
|
- else {
|
388
|
|
- // We are close enough to finish off the move.
|
389
|
|
- COPY(destination, saved_destination);
|
390
|
|
- prepare_move_to_destination();
|
391
|
|
- flags.manual_motion = false;
|
392
|
|
- }
|
393
|
|
- }
|
|
399
|
+ set_destination_from_current();
|
|
400
|
+ destination[E_AXIS] = position;
|
|
401
|
+ prepare_move_to_destination();
|
394
|
402
|
}
|
395
|
403
|
|
396
|
404
|
void setActiveTool(const extruder_t extruder, bool no_move) {
|
|
@@ -1044,7 +1052,6 @@ void MarlinUI::update() {
|
1044
|
1052
|
}
|
1045
|
1053
|
}
|
1046
|
1054
|
#endif // SDSUPPORT
|
1047
|
|
- ExtUI::_processManualMoveToDestination();
|
1048
|
1055
|
ExtUI::onIdle();
|
1049
|
1056
|
}
|
1050
|
1057
|
|