mirror of https://github.com/vitalif/GPX
parent
20fc9ef108
commit
641c7538c9
7
Makefile
7
Makefile
|
@ -3,7 +3,7 @@ CC = cc
|
|||
CC_FLAGS = -w
|
||||
|
||||
# File names
|
||||
VERSION = 1.0
|
||||
VERSION = 1.0-rc2
|
||||
PLATFORM=osx
|
||||
ARCHIVE = gpx-$(PLATFORM)-$(VERSION)
|
||||
PREFIX = /usr/local
|
||||
|
@ -23,6 +23,9 @@ gpx: $(OBJECTS)
|
|||
# To remove generated files
|
||||
clean:
|
||||
rm -f gpx $(OBJECTS)
|
||||
rm -f $(ARCHIVE).tar.gz
|
||||
rm -f $(ARCHIVE).zip
|
||||
rm -f $(ARCHIVE).dmg
|
||||
|
||||
# To install program and supporting files
|
||||
install: gpx
|
||||
|
@ -45,7 +48,7 @@ release: gpx
|
|||
cp gpx *.ini *.gcode *.py $(ARCHIVE)
|
||||
tar cf - $(ARCHIVE) | gzip -9c > $(ARCHIVE).tar.gz
|
||||
zip -r $(ARCHIVE).zip $(ARCHIVE)
|
||||
hdiutil create -format UDZO -srcfolder $(ARCHIVE) $(ARCHIVE).dmg
|
||||
test -f /usr/bin/hdiutil && hdiutil create -format UDZO -srcfolder $(ARCHIVE) $(ARCHIVE).dmg
|
||||
rm -rf $(ARCHIVE)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
;
|
||||
; example-machine.ini (custom machine definition)
|
||||
;
|
||||
; Thing-O-Matic Mk7 (dual) machine definition file
|
||||
;
|
||||
; To create your own machine definition for custom printers start
|
||||
; with a corresponding machine definition file from ReplicatorG
|
||||
; and customize from there
|
||||
;
|
||||
; http://github.com/makerbot/ReplicatorG/tree/master/machines
|
||||
|
||||
;************ MACHINE ************
|
||||
|
||||
[machine]
|
||||
|
||||
; specifies the nominal filament diameter (either 1.75 or 3.0)
|
||||
|
||||
nominal_filament_diameter=1.75
|
||||
|
||||
; spesifies the number of extruders on this machine
|
||||
|
||||
extruder_count=2
|
||||
|
||||
; sets the timeout for homing in seconds
|
||||
|
||||
timeout=20
|
||||
|
||||
;************ X AXIS ************
|
||||
|
||||
[x]
|
||||
|
||||
; sets the maximum feedrate for this axis in mm/s
|
||||
|
||||
max_feedrate=9600
|
||||
|
||||
; sets the home feedrate for this axis in mm/s
|
||||
|
||||
home_feedrate=500
|
||||
|
||||
; sets the number of steps per mm of movement for this axis
|
||||
; Pulley dia: 10.82mm / 1/8 step = 1/(10.82 * pi / 1600)
|
||||
|
||||
steps_per_mm=47.069852
|
||||
|
||||
; sets the homing direction for this axis
|
||||
; maximum = 1
|
||||
; minimum = 0
|
||||
|
||||
endstop=0
|
||||
|
||||
;************ Y AXIS ************
|
||||
|
||||
[y]
|
||||
|
||||
; sets the maximum feedrate for this axis in mm/s
|
||||
|
||||
max_feedrate=9600
|
||||
|
||||
; sets the home feedrate for this axis in mm/s
|
||||
|
||||
home_feedrate=500
|
||||
|
||||
; sets the number of steps per mm of movement for this axis
|
||||
; Pulley dia: 10.82mm / 1/8 step = 1/(10.82 * pi / 1600)
|
||||
|
||||
steps_per_mm=47.069852
|
||||
|
||||
; sets the homing direction for this axis
|
||||
; maximum = 1
|
||||
; minimum = 0
|
||||
|
||||
endstop=0
|
||||
|
||||
;************ Z AXIS ************
|
||||
|
||||
[z]
|
||||
|
||||
; sets the maximum feedrate for this axis in mm/s
|
||||
|
||||
max_feedrate=1000
|
||||
|
||||
; sets the home feedrate for this axis in mm/s
|
||||
|
||||
home_feedrate=500
|
||||
|
||||
; sets the number of steps per mm of movement for this axis
|
||||
; TR-8x8 Z axis = 1/(8/1600)
|
||||
|
||||
steps_per_mm=200
|
||||
|
||||
; sets the homing direction for this axis
|
||||
; maximum = 1
|
||||
; minimum = 0
|
||||
|
||||
endstop=1
|
||||
|
||||
;************ RIGHT EXTUDER (A AXIS) ************
|
||||
|
||||
[a]
|
||||
|
||||
; sets the maximum feedrate for this axis in mm/s
|
||||
|
||||
max_feedrate=1600
|
||||
|
||||
; sets the number of steps per mm of extrusion
|
||||
; Steps/mm is calculated by dividing the 'drive gear steps per revolution'
|
||||
; (in this case, equal to motor_steps) by the 'drive gear circumference'
|
||||
; (drive gear diameter = 10.14) So we get: 1600/(PI * 0.14) = 50.235....
|
||||
|
||||
steps_per_mm=50.235478806907409
|
||||
|
||||
; sets the number of steps per revolution
|
||||
|
||||
motor_steps=1600
|
||||
|
||||
; signals if this tool has a heated build platform
|
||||
|
||||
has_heated_build_platform=0
|
||||
|
||||
;************ LEFT EXTUDER (B AXIS) ************
|
||||
|
||||
[b]
|
||||
|
||||
; sets the maximum feedrate for this axis in mm/s
|
||||
|
||||
max_feedrate=1600
|
||||
|
||||
; sets the number of steps per mm of extrusion
|
||||
|
||||
steps_per_mm=50.235478806907409
|
||||
|
||||
; sets the number of steps per revolution
|
||||
|
||||
motor_steps=1600
|
||||
|
||||
; signals if this tool has a heated build platform
|
||||
|
||||
has_heated_build_platform=1
|
|
@ -0,0 +1,15 @@
|
|||
#
|
||||
# example-pause-at-zpos.ini (macro script)
|
||||
#
|
||||
|
||||
[macro]
|
||||
|
||||
slicer: 1.70mm
|
||||
|
||||
filament: blue 1.72mm 230c #000FF
|
||||
filament: red 1.69mm 220c #FF0000
|
||||
filament: white 1.75mm 210c #FFFFFF
|
||||
|
||||
start: white ; start with white filament
|
||||
pause: 3.0 red ; pause @ zPos 3mm and change to red filament
|
||||
pause: 6.0 blue ; pause @ zPos 6mm and change to blue filament
|
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# example-temperature.ini (macro script)
|
||||
#
|
||||
|
||||
[macro]
|
||||
|
||||
slicer: 1.75mm
|
||||
|
||||
filament: wood 1.75mm 240c #FFFFFF
|
||||
|
||||
start: wood ; start with wood filament
|
||||
|
||||
temperature: 1.0 180c
|
||||
temperature: 4.0 240c
|
||||
temperature: 5.0 180c
|
||||
temperature: 8.0 240c
|
||||
temperature: 9.0 180c
|
||||
temperature: 12.0 240c
|
||||
temperature: 13.0 180c
|
80
example.ini
80
example.ini
|
@ -1,80 +0,0 @@
|
|||
;
|
||||
; example.ini (custom machine definition)
|
||||
;
|
||||
; Replicator 2 machine definition file
|
||||
;
|
||||
; To create your own machine definition for different printers like the
|
||||
;
|
||||
|
||||
; specifies the axis
|
||||
|
||||
[x]
|
||||
|
||||
;sets the maximum feedrate for this axis in mm/s
|
||||
|
||||
max_feedrate=18000
|
||||
|
||||
;sets the home feedrate for this axis in mm/s
|
||||
|
||||
home_feedrate=2500
|
||||
|
||||
;sets the number of steps per mm of movement for this axis
|
||||
|
||||
steps_per_mm=88.573186
|
||||
|
||||
; sets the homing direction for this axis
|
||||
; maximum = 1
|
||||
; minimum = 0
|
||||
|
||||
endstop=1
|
||||
|
||||
[y]
|
||||
max_feedrate=18000
|
||||
home_feedrate=2500
|
||||
steps_per_mm=88.573186
|
||||
endstop=1
|
||||
|
||||
[z]
|
||||
max_feedrate=1170
|
||||
home_feedrate=1100
|
||||
steps_per_mm=400
|
||||
endstop=0
|
||||
|
||||
; specifies the right extruder
|
||||
|
||||
[a]
|
||||
|
||||
; sets the maximum feedrate for this axis in mm/s
|
||||
|
||||
max_feedrate=1600
|
||||
|
||||
; sets the number of steps per mm of extrusion
|
||||
|
||||
steps_per_mm=96.275201870333662468889989185642
|
||||
|
||||
; sets the number of steps per revolution
|
||||
|
||||
motor_steps=3200
|
||||
|
||||
; signals if this tool has a heated build platform (unually a does)
|
||||
|
||||
has_heated_build_platform=0
|
||||
|
||||
[b]
|
||||
max_feedrate=1600
|
||||
steps_per_mm=96.275201870333662468889989185642
|
||||
motor_steps=3200
|
||||
|
||||
[machine]
|
||||
|
||||
; specifies the nominal filament diameter (either 1.75 or 3.0)
|
||||
|
||||
nominal_filament_diameter=1.75
|
||||
|
||||
; spesifies the number of extruders on this machine
|
||||
|
||||
extruder_count=1
|
||||
|
||||
; sets the timeout for homing in seconds
|
||||
|
||||
timeout=20
|
8
getopt.c
8
getopt.c
|
@ -19,12 +19,11 @@ unix/linux platforms.
|
|||
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include "getopt.h"
|
||||
|
||||
#include <string.h>
|
||||
#if defined(_MSC_VER)
|
||||
# include <io.h>
|
||||
#endif
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -81,3 +80,6 @@ int getopt(int argc, char **argv, char *opts)
|
|||
}
|
||||
return(c);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
774
gpx.c
774
gpx.c
|
@ -94,6 +94,9 @@ static Machine cupcake_PP = {
|
|||
20, // timeout
|
||||
};
|
||||
|
||||
// Axis - max_feedrate, home_feedrate, steps_per_mm, endstop;
|
||||
// Extruder - max_feedrate, steps_per_mm, motor_steps, has_heated_build_platform;
|
||||
|
||||
static Machine thing_o_matic_7 = {
|
||||
{9600, 500, 47.069852, ENDSTOP_IS_MIN}, // x axis
|
||||
{9600, 500, 47.069852, ENDSTOP_IS_MIN}, // y axis
|
||||
|
@ -117,6 +120,9 @@ static Machine thing_o_matic_7D = {
|
|||
};
|
||||
|
||||
|
||||
// Axis - max_feedrate, home_feedrate, steps_per_mm, endstop;
|
||||
// Extruder - max_feedrate, steps_per_mm, motor_steps, has_heated_build_platform;
|
||||
|
||||
static Machine replicator_1 = {
|
||||
{18000, 2500, 94.139704, ENDSTOP_IS_MAX}, // x axis
|
||||
{18000, 2500, 94.139704, ENDSTOP_IS_MAX}, // y axis
|
||||
|
@ -139,6 +145,9 @@ static Machine replicator_1D = {
|
|||
20, // timeout
|
||||
};
|
||||
|
||||
// Axis - max_feedrate, home_feedrate, steps_per_mm, endstop;
|
||||
// Extruder - max_feedrate, steps_per_mm, motor_steps, has_heated_build_platform;
|
||||
|
||||
static Machine replicator_2 = {
|
||||
{18000, 2500, 88.573186, ENDSTOP_IS_MAX}, // x axis
|
||||
{18000, 2500, 88.573186, ENDSTOP_IS_MAX}, // y axis
|
||||
|
@ -177,8 +186,6 @@ Machine machine = {
|
|||
// PRIVATE FUNCTION PROTOTYPES
|
||||
|
||||
static double get_home_feedrate(int flag);
|
||||
static void set_nozzle_temperature(unsigned extruder_id, unsigned temperature);
|
||||
static void set_LED_RGB(unsigned rgb, unsigned blink);
|
||||
static void pause_at_zpos(float z_positon);
|
||||
|
||||
// GLOBAL VARIABLES
|
||||
|
@ -206,9 +213,12 @@ static char buffer[300]; // the statically allocated parse-in-place buffer
|
|||
Filament filament[FILAMENT_MAX];
|
||||
int filamentLength;
|
||||
|
||||
PauseAt pauseAt[PAUSE_AT_MAX];
|
||||
int pauseAtIndex;
|
||||
int pauseAtLength;
|
||||
CommandAt commandAt[COMMAND_AT_MAX];
|
||||
int commandAtIndex;
|
||||
int commandAtLength;
|
||||
|
||||
int atTemperature; // are we at temperature - hopefully signals homing is over
|
||||
int pausePending; //
|
||||
|
||||
FILE *in; // the gcode input file stream
|
||||
FILE *out; // the x3g output file stream
|
||||
|
@ -315,8 +325,10 @@ static void initialize_globals(void)
|
|||
filament[0].LED = 0;
|
||||
filamentLength = 1;
|
||||
|
||||
pauseAtIndex = 0;
|
||||
pauseAtLength = 0;
|
||||
commandAtIndex = 0;
|
||||
commandAtLength = 0;
|
||||
atTemperature = 0;
|
||||
pausePending = 0;
|
||||
}
|
||||
|
||||
// STATE
|
||||
|
@ -409,111 +421,7 @@ static size_t write_string(char *string, long length)
|
|||
return bytes_sent;
|
||||
}
|
||||
|
||||
// Custom machine definition ini handler
|
||||
|
||||
#define SECTION_IS(s) strcasecmp(section, s) == 0
|
||||
#define NAME_IS(n) strcasecmp(name, n) == 0
|
||||
#define VALUE_IS(v) strcasecmp(value, v) == 0
|
||||
|
||||
static int config_handler(void* user, const char* section, const char* name, const char* value)
|
||||
{
|
||||
if(SECTION_IS("printer")) {
|
||||
if(NAME_IS("ditto_printing")) dittoPrinting = atoi(value);
|
||||
else if(NAME_IS("build_progress")) buildProgress = atoi(value);
|
||||
else if(NAME_IS("nominal_filament_diameter")
|
||||
|| NAME_IS("slicer_filament_diameter")) machine.nominal_filament_diameter = strtod(value, NULL);
|
||||
else if(NAME_IS("machine_type")) {
|
||||
// use on-board machine definition
|
||||
if(VALUE_IS("c3")) machine = cupcake_G3;
|
||||
else if(VALUE_IS("c4")) machine = cupcake_G4;
|
||||
else if(VALUE_IS("cp4")) machine = cupcake_P4;
|
||||
else if(VALUE_IS("cpp")) machine = cupcake_PP;
|
||||
else if(VALUE_IS("t7")) machine = thing_o_matic_7;
|
||||
else if(VALUE_IS("t6")) machine = thing_o_matic_7;
|
||||
else if(VALUE_IS("t7")) machine = thing_o_matic_7;
|
||||
else if(VALUE_IS("t7d")) machine = thing_o_matic_7D;
|
||||
else if(VALUE_IS("r1")) machine = replicator_1;
|
||||
else if(VALUE_IS("r1d")) machine = replicator_1D;
|
||||
else if(VALUE_IS("r2")) machine = replicator_2;
|
||||
else if(VALUE_IS("r2x")) machine = replicator_2X;
|
||||
else {
|
||||
fprintf(stderr, "Configuration error: unrecognised machine type '%s'" EOL, value);
|
||||
}
|
||||
}
|
||||
else if(NAME_IS("build_platform_temperature")) {
|
||||
if(machine.a.has_heated_build_platform) override[A].build_platform_temperature = atoi(value);
|
||||
else if(machine.b.has_heated_build_platform) override[B].build_platform_temperature = atoi(value);
|
||||
}
|
||||
else if(NAME_IS("sd_card_path")) {
|
||||
sdCardPath = strdup(value);
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
else if(SECTION_IS("x")) {
|
||||
if(NAME_IS("max_feedrate")) machine.x.max_feedrate = strtod(value, NULL);
|
||||
else if(NAME_IS("home_feedrate")) machine.x.home_feedrate = strtod(value, NULL);
|
||||
else if(NAME_IS("steps_per_mm")) machine.x.steps_per_mm = strtod(value, NULL);
|
||||
else if(NAME_IS("endstop")) machine.x.endstop = atoi(value);
|
||||
else return 0;
|
||||
}
|
||||
else if(SECTION_IS("y")) {
|
||||
if(NAME_IS("max_feedrate")) machine.y.max_feedrate = strtod(value, NULL);
|
||||
else if(NAME_IS("home_feedrate")) machine.y.home_feedrate = strtod(value, NULL);
|
||||
else if(NAME_IS("steps_per_mm")) machine.y.steps_per_mm = strtod(value, NULL);
|
||||
else if(NAME_IS("endstop")) machine.y.endstop = atoi(value);
|
||||
else return 0;
|
||||
}
|
||||
else if(SECTION_IS("z")) {
|
||||
if(NAME_IS("max_feedrate")) machine.z.max_feedrate = strtod(value, NULL);
|
||||
else if(NAME_IS("home_feedrate")) machine.z.home_feedrate = strtod(value, NULL);
|
||||
else if(NAME_IS("steps_per_mm")) machine.z.steps_per_mm = strtod(value, NULL);
|
||||
else if(NAME_IS("endstop")) machine.z.endstop = atoi(value);
|
||||
else return 0;
|
||||
}
|
||||
else if(SECTION_IS("a")) {
|
||||
if(NAME_IS("max_feedrate")) machine.a.max_feedrate = strtod(value, NULL);
|
||||
else if(NAME_IS("steps_per_mm")) machine.a.steps_per_mm = strtod(value, NULL);
|
||||
else if(NAME_IS("motor_steps")) machine.a.motor_steps = strtod(value, NULL);
|
||||
else if(NAME_IS("has_heated_build_platform")) machine.a.has_heated_build_platform = atoi(value);
|
||||
else return 0;
|
||||
}
|
||||
else if(SECTION_IS("right")) {
|
||||
if(NAME_IS("active_temperature")
|
||||
|| NAME_IS("nozzle_temperature")) override[A].active_temperature = atoi(value);
|
||||
else if(NAME_IS("standby_temperature")) override[A].standby_temperature = atoi(value);
|
||||
else if(NAME_IS("build_platform_temperature")) override[A].build_platform_temperature = atoi(value);
|
||||
else if(NAME_IS("actual_filament_diameter")) override[A].actual_filament_diameter = strtod(value, NULL);
|
||||
else return 0;
|
||||
}
|
||||
else if(SECTION_IS("b")) {
|
||||
if(NAME_IS("max_feedrate")) machine.b.max_feedrate = strtod(value, NULL);
|
||||
else if(NAME_IS("steps_per_mm")) machine.b.steps_per_mm = strtod(value, NULL);
|
||||
else if(NAME_IS("motor_steps")) machine.b.motor_steps = strtod(value, NULL);
|
||||
else if(NAME_IS("has_heated_build_platform")) machine.b.has_heated_build_platform = atoi(value);
|
||||
else return 0;
|
||||
}
|
||||
else if(SECTION_IS("left")) {
|
||||
if(NAME_IS("active_temperature")
|
||||
|| NAME_IS("nozzle_temperature")) override[B].active_temperature = atoi(value);
|
||||
else if(NAME_IS("standby_temperature")) override[B].standby_temperature = atoi(value);
|
||||
else if(NAME_IS("build_platform_temperature")) override[B].build_platform_temperature = atoi(value);
|
||||
else if(NAME_IS("actual_filament_diameter")) override[B].actual_filament_diameter = strtod(value, NULL);
|
||||
else return 0;
|
||||
}
|
||||
else if(SECTION_IS("machine")) {
|
||||
if(NAME_IS("nominal_filament_diameter")
|
||||
|| NAME_IS("slicer_filament_diameter")) machine.nominal_filament_diameter = strtod(value, NULL);
|
||||
else if(NAME_IS("extruder_count")) machine.extruder_count = atoi(value);
|
||||
else if(NAME_IS("timeout")) machine.timeout = atoi(value);
|
||||
else return 0;
|
||||
}
|
||||
else {
|
||||
return 0; // unknown section/name, error
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// PAUSE @ ZPOS FUNCTIONS
|
||||
// COMMAND @ ZPOS FUNCTIONS
|
||||
|
||||
// find an existing filament definition
|
||||
|
||||
|
@ -551,40 +459,59 @@ static int add_filament(char *filament_id, double diameter, unsigned temperature
|
|||
return index;
|
||||
}
|
||||
|
||||
// append a new pause at z function
|
||||
// append a new command at z function
|
||||
|
||||
static int add_pause_at(double z, char *filament_id)
|
||||
static void add_command_at(double z, char *filament_id, unsigned temperature)
|
||||
{
|
||||
static double previous_z = 0.0;
|
||||
if(z <= previous_z) {
|
||||
fprintf(stderr, "(line %u) Semantic error: @pause at z pos %f lower than previous z %f" EOL, lineNumber, z, previous_z);
|
||||
exit(1);
|
||||
}
|
||||
int index = filament_id ? find_filament(filament_id) : 0;
|
||||
if(index < 0) {
|
||||
fprintf(stderr, "(line %u) Semantic error: @pause macro with undefined filament name '%s', use a @filament macro to define it" EOL, lineNumber, filament_id);
|
||||
index = 0;
|
||||
}
|
||||
if(pauseAtLength < PAUSE_AT_MAX) {
|
||||
pauseAt[pauseAtLength].z = z;
|
||||
pauseAt[pauseAtLength].filament_index = index;
|
||||
pauseAtLength++;
|
||||
if(pauseAtLength == 1) {
|
||||
pause_at_zpos(z);
|
||||
// insert command
|
||||
if(commandAtLength < COMMAND_AT_MAX) {
|
||||
if(z <= previous_z) {
|
||||
int i = commandAtLength;
|
||||
// make a space
|
||||
while(i > 0 && z <= commandAt[i - 1].z) {
|
||||
commandAt[i] = commandAt[i - 1];
|
||||
i--;
|
||||
}
|
||||
commandAt[i].z = z;
|
||||
commandAt[i].filament_index = index;
|
||||
commandAt[i].temperature = temperature;
|
||||
previous_z = commandAt[commandAtLength].z;
|
||||
}
|
||||
// append command
|
||||
else {
|
||||
commandAt[commandAtLength].z = z;
|
||||
commandAt[commandAtLength].filament_index = index;
|
||||
commandAt[commandAtLength].temperature = temperature;
|
||||
previous_z = z;
|
||||
}
|
||||
// nonzero temperature signals a tmperature change, not a pause @ zPos
|
||||
if(temperature == 0 && commandAtLength == 0) {
|
||||
if(atTemperature) {
|
||||
pause_at_zpos(z);
|
||||
}
|
||||
else {
|
||||
pausePending = 1;
|
||||
}
|
||||
}
|
||||
commandAtLength++;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "(line %u) Buffer overflow: too many @pause definitions (maximum = %i)" EOL, lineNumber, PAUSE_AT_MAX);
|
||||
index = 0;
|
||||
fprintf(stderr, "(line %u) Buffer overflow: too many @pause definitions (maximum = %i)" EOL, lineNumber, COMMAND_AT_MAX);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
// 5D VECTOR FUNCTIONS
|
||||
|
||||
// compute the filament scaling factor
|
||||
|
||||
static void set_filament_scale(unsigned extruder_id, double filament_diameter) {
|
||||
static void set_filament_scale(unsigned extruder_id, double filament_diameter)
|
||||
{
|
||||
double actual_radius = filament_diameter / 2;
|
||||
double nominal_radius = machine.nominal_filament_diameter / 2;
|
||||
override[extruder_id].filament_scale = (nominal_radius * nominal_radius) / (actual_radius * actual_radius);
|
||||
|
@ -755,119 +682,6 @@ static Point5d mm_to_steps(Ptr5d mm, Ptr2d excess)
|
|||
return result;
|
||||
}
|
||||
|
||||
// calculate target position
|
||||
|
||||
static int calculate_target_position(void)
|
||||
{
|
||||
int do_pause_at_zpos = 0;
|
||||
|
||||
// CALCULATE TARGET POSITION
|
||||
|
||||
// x
|
||||
if(command.flag & X_IS_SET) {
|
||||
targetPosition.x = isRelative ? (currentPosition.x + command.x) : (command.x + offset[currentOffset].x);
|
||||
}
|
||||
else {
|
||||
targetPosition.x = currentPosition.x;
|
||||
}
|
||||
|
||||
// y
|
||||
if(command.flag & Y_IS_SET) {
|
||||
targetPosition.y = isRelative ? (currentPosition.y + command.y) : (command.y + offset[currentOffset].y);
|
||||
}
|
||||
else {
|
||||
targetPosition.y = currentPosition.y;
|
||||
}
|
||||
|
||||
// z
|
||||
if(command.flag & Z_IS_SET) {
|
||||
targetPosition.z = isRelative ? (currentPosition.z + command.z) : (command.z + offset[currentOffset].z);
|
||||
}
|
||||
else {
|
||||
targetPosition.z = currentPosition.z;
|
||||
}
|
||||
|
||||
// a
|
||||
if(command.flag & A_IS_SET) {
|
||||
targetPosition.a = (isRelative || extruderIsRelative) ? (currentPosition.a + command.a) : command.a;
|
||||
}
|
||||
else {
|
||||
targetPosition.a = currentPosition.a;
|
||||
}
|
||||
// b
|
||||
if(command.flag & B_IS_SET) {
|
||||
targetPosition.b = (isRelative || extruderIsRelative) ? (currentPosition.b + command.b) : command.b;
|
||||
}
|
||||
else {
|
||||
targetPosition.b = currentPosition.b;
|
||||
}
|
||||
|
||||
// update current feedrate
|
||||
if(command.flag & F_IS_SET) {
|
||||
currentFeedrate = command.f;
|
||||
}
|
||||
|
||||
// DITTO PRINTING
|
||||
|
||||
if(dittoPrinting) {
|
||||
if(command.flag & A_IS_SET) {
|
||||
targetPosition.b = targetPosition.a;
|
||||
command.flag |= B_IS_SET;
|
||||
}
|
||||
else if(command.flag & B_IS_SET) {
|
||||
targetPosition.a = targetPosition.b;
|
||||
command.flag |= A_IS_SET;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK FOR PAUSE @ Z POS
|
||||
|
||||
if(pauseAtIndex < pauseAtLength) {
|
||||
// check if the next command will cross the threshold
|
||||
if(pauseAt[pauseAtIndex].z <= targetPosition.z) {
|
||||
int index = pauseAt[pauseAtIndex].filament_index;
|
||||
// override filament diameter
|
||||
if(filament[index].diameter > 0.0001) {
|
||||
if(dittoPrinting) {
|
||||
set_filament_scale(A, filament[index].diameter);
|
||||
set_filament_scale(B, filament[index].diameter);
|
||||
}
|
||||
else {
|
||||
set_filament_scale(currentExtruder, filament[index].diameter);
|
||||
}
|
||||
}
|
||||
// override nozzle temperature
|
||||
if(filament[index].temperature
|
||||
&& tool[currentExtruder].nozzle_temperature != filament[index].temperature) {
|
||||
if(dittoPrinting) {
|
||||
set_nozzle_temperature(A, filament[index].temperature);
|
||||
set_nozzle_temperature(B, filament[index].temperature);
|
||||
tool[A].nozzle_temperature = tool[B].nozzle_temperature = filament[index].temperature;
|
||||
}
|
||||
else {
|
||||
set_nozzle_temperature(currentExtruder, filament[index].temperature);
|
||||
tool[currentExtruder].nozzle_temperature = filament[index].temperature;
|
||||
}
|
||||
}
|
||||
// override LED colour
|
||||
if(filament[index].LED) {
|
||||
set_LED_RGB(filament[index].LED, 0);
|
||||
}
|
||||
pauseAtIndex++;
|
||||
if(pauseAtIndex < pauseAtLength) {
|
||||
do_pause_at_zpos = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SCALE FILAMENT INDEPENDENTLY
|
||||
|
||||
if(command.flag & A_IS_SET && override[A].filament_scale != 1.0) targetPosition.a *= override[A].filament_scale;
|
||||
if(command.flag & B_IS_SET && override[B].filament_scale != 1.0) targetPosition.b *= override[B].filament_scale;
|
||||
|
||||
return do_pause_at_zpos;
|
||||
}
|
||||
|
||||
// X3G COMMANDS
|
||||
|
||||
// 131 - Find axes minimums
|
||||
|
@ -1605,6 +1419,173 @@ static void pause_at_zpos(float z_positon)
|
|||
write_float(z_positon);
|
||||
}
|
||||
|
||||
// TARGET POSITION
|
||||
|
||||
// calculate target position
|
||||
|
||||
static int calculate_target_position(void)
|
||||
{
|
||||
int do_pause_at_zpos = 0;
|
||||
|
||||
// CALCULATE TARGET POSITION
|
||||
|
||||
// x
|
||||
if(command.flag & X_IS_SET) {
|
||||
targetPosition.x = isRelative ? (currentPosition.x + command.x) : (command.x + offset[currentOffset].x);
|
||||
}
|
||||
else {
|
||||
targetPosition.x = currentPosition.x;
|
||||
}
|
||||
|
||||
// y
|
||||
if(command.flag & Y_IS_SET) {
|
||||
targetPosition.y = isRelative ? (currentPosition.y + command.y) : (command.y + offset[currentOffset].y);
|
||||
}
|
||||
else {
|
||||
targetPosition.y = currentPosition.y;
|
||||
}
|
||||
|
||||
// z
|
||||
if(command.flag & Z_IS_SET) {
|
||||
targetPosition.z = isRelative ? (currentPosition.z + command.z) : (command.z + offset[currentOffset].z);
|
||||
}
|
||||
else {
|
||||
targetPosition.z = currentPosition.z;
|
||||
}
|
||||
|
||||
// a
|
||||
if(command.flag & A_IS_SET) {
|
||||
targetPosition.a = (isRelative || extruderIsRelative) ? (currentPosition.a + command.a) : command.a;
|
||||
}
|
||||
else {
|
||||
targetPosition.a = currentPosition.a;
|
||||
}
|
||||
// b
|
||||
if(command.flag & B_IS_SET) {
|
||||
targetPosition.b = (isRelative || extruderIsRelative) ? (currentPosition.b + command.b) : command.b;
|
||||
}
|
||||
else {
|
||||
targetPosition.b = currentPosition.b;
|
||||
}
|
||||
|
||||
// update current feedrate
|
||||
if(command.flag & F_IS_SET) {
|
||||
currentFeedrate = command.f;
|
||||
}
|
||||
|
||||
// DITTO PRINTING
|
||||
|
||||
if(dittoPrinting) {
|
||||
if(command.flag & A_IS_SET) {
|
||||
targetPosition.b = targetPosition.a;
|
||||
command.flag |= B_IS_SET;
|
||||
}
|
||||
else if(command.flag & B_IS_SET) {
|
||||
targetPosition.a = targetPosition.b;
|
||||
command.flag |= A_IS_SET;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK FOR COMMAND @ Z POS
|
||||
|
||||
// check if there are more commands on the stack
|
||||
if(atTemperature && commandAtIndex < commandAtLength) {
|
||||
// check if the next command will cross the z threshold
|
||||
if(commandAt[commandAtIndex].z <= targetPosition.z) {
|
||||
// is this a temperature change macro?
|
||||
if(commandAt[commandAtIndex].temperature) {
|
||||
unsigned temperature = commandAt[commandAtIndex].temperature;
|
||||
// make sure the temperature has changed
|
||||
if(tool[currentExtruder].nozzle_temperature != temperature) {
|
||||
if(dittoPrinting) {
|
||||
set_nozzle_temperature(A, temperature);
|
||||
set_nozzle_temperature(B, temperature);
|
||||
tool[A].nozzle_temperature = tool[B].nozzle_temperature = temperature;
|
||||
}
|
||||
else {
|
||||
set_nozzle_temperature(currentExtruder, temperature);
|
||||
tool[currentExtruder].nozzle_temperature = temperature;
|
||||
}
|
||||
}
|
||||
commandAtIndex++;
|
||||
}
|
||||
// no its a pause macro
|
||||
else {
|
||||
int index = commandAt[commandAtIndex].filament_index;
|
||||
// override filament diameter
|
||||
if(filament[index].diameter > 0.0001) {
|
||||
if(dittoPrinting) {
|
||||
set_filament_scale(A, filament[index].diameter);
|
||||
set_filament_scale(B, filament[index].diameter);
|
||||
}
|
||||
else {
|
||||
set_filament_scale(currentExtruder, filament[index].diameter);
|
||||
}
|
||||
}
|
||||
// override nozzle temperature
|
||||
if(filament[index].temperature) {
|
||||
unsigned temperature = filament[index].temperature;
|
||||
if(tool[currentExtruder].nozzle_temperature != temperature) {
|
||||
if(dittoPrinting) {
|
||||
set_nozzle_temperature(A, temperature);
|
||||
set_nozzle_temperature(B, temperature);
|
||||
tool[A].nozzle_temperature = tool[B].nozzle_temperature = temperature;
|
||||
}
|
||||
else {
|
||||
set_nozzle_temperature(currentExtruder, temperature);
|
||||
tool[currentExtruder].nozzle_temperature = temperature;
|
||||
}
|
||||
}
|
||||
}
|
||||
// override LED colour
|
||||
if(filament[index].LED) {
|
||||
set_LED_RGB(filament[index].LED, 0);
|
||||
}
|
||||
commandAtIndex++;
|
||||
if(commandAtIndex < commandAtLength) {
|
||||
do_pause_at_zpos = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SCALE FILAMENT INDEPENDENTLY
|
||||
|
||||
if(command.flag & A_IS_SET && override[A].filament_scale != 1.0) targetPosition.a *= override[A].filament_scale;
|
||||
if(command.flag & B_IS_SET && override[B].filament_scale != 1.0) targetPosition.b *= override[B].filament_scale;
|
||||
|
||||
return do_pause_at_zpos;
|
||||
}
|
||||
|
||||
// TOOL CHANGE
|
||||
|
||||
void do_tool_change(int timeout) {
|
||||
// set the temperature of current tool to standby (if standby is different to active)
|
||||
if(override[currentExtruder].standby_temperature
|
||||
&& override[currentExtruder].standby_temperature != tool[currentExtruder].nozzle_temperature) {
|
||||
unsigned temperature = override[currentExtruder].standby_temperature;
|
||||
set_nozzle_temperature(currentExtruder, temperature);
|
||||
tool[currentExtruder].nozzle_temperature = temperature;
|
||||
}
|
||||
// set the temperature of selected tool to active (if active is different to standby)
|
||||
if(override[selectedExtruder].active_temperature
|
||||
&& override[selectedExtruder].active_temperature != tool[selectedExtruder].nozzle_temperature) {
|
||||
unsigned temperature = override[selectedExtruder].active_temperature;
|
||||
set_nozzle_temperature(selectedExtruder, temperature);
|
||||
tool[selectedExtruder].nozzle_temperature = temperature;
|
||||
// wait for nozzle to head up
|
||||
wait_for_extruder(selectedExtruder, timeout);
|
||||
}
|
||||
// switch any active G10 offset (G54 or G55)
|
||||
if(currentOffset == currentExtruder + 1) {
|
||||
currentOffset = selectedExtruder + 1;
|
||||
}
|
||||
// change current toolhead in order to apply the calibration offset
|
||||
change_extruder_offset(selectedExtruder);
|
||||
// set current extruder so changes in E are expressed as changes to A or B
|
||||
currentExtruder = selectedExtruder;
|
||||
}
|
||||
|
||||
// PARSER PRE-PROCESSOR
|
||||
|
||||
// return the length of the given file in bytes
|
||||
|
@ -1684,7 +1665,7 @@ static char *normalize_comment(char *p) {
|
|||
COMMAND:= PRINTER | ENABLE | FILAMENT | EXTRUDER | SLICER | START| PAUSE
|
||||
COMMENT:= S+ '(' [^)]* ')' S+
|
||||
PRINTER:= ('printer' | 'machine') (TYPE | DIAMETER | TEMP | RGB)+
|
||||
TYPE:= S+ ('r1' | 'r1d' | 'r2' | 'r2x')
|
||||
TYPE:= S+ ('c3' | 'c4' | 'cp4' | 'cpp' | 't6' | 't7' | 't7d' | 'r1' | 'r1d' | 'r2' | 'r2x')
|
||||
DIAMETER:= S+ DIGIT+ ('.' DIGIT+)? 'm' 'm'?
|
||||
TEMP:= S+ DIGIT+ 'c'
|
||||
RGB:= S+ '#' HEX HEX HEX HEX HEX HEX ; LED colour
|
||||
|
@ -1695,29 +1676,23 @@ static char *normalize_comment(char *p) {
|
|||
FILAMENT_ID:= S+ ALPHA+ ALPHA_NUMERIC*
|
||||
EXTRUDER:= ('right' | 'left') (FILAMENT_ID | DIAMETER | TEMP)+
|
||||
SLICER:= 'slicer' DIAMETER ; Nominal filament diameter
|
||||
START:= 'start' FILAMENT_ID
|
||||
PAUSE:= 'pause' (ZPOS | FILAMENT_ID)+
|
||||
START:= 'start' (FILAMENT_ID | TEMPERATURE)
|
||||
PAUSE:= 'pause' (ZPOS | FILAMENT_ID | TEMPERATURE)+
|
||||
ZPOS:= S+ DIGIT+ ('.' DIGIT+)?
|
||||
|
||||
*/
|
||||
|
||||
#define MACRO_IS(token) strcmp(token, macro) == 0
|
||||
#define NAME_IS(n) strcasecmp(name, n) == 0
|
||||
|
||||
static void parse_macro(char *p)
|
||||
static void parse_macro(const char* macro, char *p)
|
||||
{
|
||||
char *macro;
|
||||
char *name = NULL;
|
||||
double z = 0.0;
|
||||
double diameter = 0.0;
|
||||
unsigned temperature = 0;
|
||||
unsigned LED = 0;
|
||||
if(!isalpha(*p)) {
|
||||
return;
|
||||
}
|
||||
macro = p;
|
||||
p++;
|
||||
while(*p && !isspace(*p)) p++;
|
||||
if(*p) *p++ = 0;
|
||||
|
||||
while(*p != 0) {
|
||||
// trim any leading white space
|
||||
while(isspace(*p)) p++;
|
||||
|
@ -1768,7 +1743,6 @@ static void parse_macro(char *p)
|
|||
else if(NAME_IS("c4")) machine = cupcake_G4;
|
||||
else if(NAME_IS("cp4")) machine = cupcake_P4;
|
||||
else if(NAME_IS("cpp")) machine = cupcake_PP;
|
||||
else if(NAME_IS("t7")) machine = thing_o_matic_7;
|
||||
else if(NAME_IS("t6")) machine = thing_o_matic_7;
|
||||
else if(NAME_IS("t7")) machine = thing_o_matic_7;
|
||||
else if(NAME_IS("t7d")) machine = thing_o_matic_7D;
|
||||
|
@ -1812,7 +1786,7 @@ static void parse_macro(char *p)
|
|||
fprintf(stderr, "(line %u) Syntax error: @enable macro with missing parameter" EOL, lineNumber);
|
||||
}
|
||||
}
|
||||
// ;@filament <NAME> <DIAMETER>mm <TEMP>c #<LED-COLOUR> (MESSAGE)
|
||||
// ;@filament <NAME> <DIAMETER>mm <TEMP>c #<LED-COLOUR>
|
||||
else if(MACRO_IS("filament")) {
|
||||
if(name) {
|
||||
add_filament(name, diameter, temperature, LED);
|
||||
|
@ -1849,58 +1823,184 @@ static void parse_macro(char *p)
|
|||
}
|
||||
// ;@pause <ZPOS> <NAME>
|
||||
else if(MACRO_IS("pause")) {
|
||||
add_pause_at(z, name);
|
||||
if(z > 0.0001) {
|
||||
add_command_at(z, name, 0);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "(line %u) Semantic error: @pause macro with missing zPos" EOL, lineNumber);
|
||||
}
|
||||
}
|
||||
else if(MACRO_IS("start")) {
|
||||
int index = find_filament(name);
|
||||
if(index > 0) {
|
||||
if(dittoPrinting) {
|
||||
if(filament[index].diameter > 0.0001) {
|
||||
set_filament_scale(A, filament[index].diameter);
|
||||
set_filament_scale(B, filament[index].diameter);
|
||||
}
|
||||
if(filament[index].temperature) {
|
||||
override[A].active_temperature = override[B].active_temperature = filament[index].temperature;
|
||||
}
|
||||
// ;@temp <ZPOS> <TEMP>c
|
||||
// ;@temperature <ZPOS> <TEMP>c
|
||||
else if(MACRO_IS("temp") || MACRO_IS("temperature")) {
|
||||
if(temperature) {
|
||||
if(z > 0.0001) {
|
||||
add_command_at(z, NULL, temperature);
|
||||
}
|
||||
else {
|
||||
if(filament[index].diameter > 0.0001) set_filament_scale(currentExtruder, filament[index].diameter);
|
||||
if(filament[index].temperature) override[currentExtruder].active_temperature = filament[index].temperature;
|
||||
if(filament[index].LED) set_LED_RGB(filament[index].LED, 0);
|
||||
fprintf(stderr, "(line %u) Semantic error: @%s macro with missing zPos" EOL, lineNumber, macro);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "(line %u) Semantic error: @start with undefined filament name '%s', use a @filament macro to define it" EOL, lineNumber, name ? name : "");
|
||||
index = 0;
|
||||
fprintf(stderr, "(line %u) Semantic error: @%s macro with missing temperature" EOL, lineNumber, macro);
|
||||
}
|
||||
}
|
||||
// ;@start <NAME> <TEMP>c
|
||||
else if(MACRO_IS("start")) {
|
||||
if(temperature) {
|
||||
if(dittoPrinting) {
|
||||
override[A].active_temperature = override[B].active_temperature = temperature;
|
||||
}
|
||||
else {
|
||||
override[currentExtruder].active_temperature = temperature;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int index = find_filament(name);
|
||||
if(index > 0) {
|
||||
if(dittoPrinting) {
|
||||
if(filament[index].diameter > 0.0001) {
|
||||
set_filament_scale(A, filament[index].diameter);
|
||||
set_filament_scale(B, filament[index].diameter);
|
||||
}
|
||||
if(filament[index].temperature) {
|
||||
override[A].active_temperature = override[B].active_temperature = filament[index].temperature;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(filament[index].diameter > 0.0001) set_filament_scale(currentExtruder, filament[index].diameter);
|
||||
if(filament[index].temperature) override[currentExtruder].active_temperature = filament[index].temperature;
|
||||
if(filament[index].LED) set_LED_RGB(filament[index].LED, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "(line %u) Semantic error: @start with undefined filament name '%s', use a @filament macro to define it" EOL, lineNumber, name ? name : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void do_tool_change(int timeout) {
|
||||
// set the temperature of current tool to standby (if standby is different to active)
|
||||
if(override[currentExtruder].standby_temperature
|
||||
&& override[currentExtruder].standby_temperature != tool[currentExtruder].nozzle_temperature) {
|
||||
unsigned temperature = override[currentExtruder].standby_temperature;
|
||||
set_nozzle_temperature(currentExtruder, temperature);
|
||||
tool[currentExtruder].nozzle_temperature = temperature;
|
||||
// INI FILE HANDLER
|
||||
|
||||
// Custom machine definition ini handler
|
||||
|
||||
#define SECTION_IS(s) strcasecmp(section, s) == 0
|
||||
#define PROPERTY_IS(n) strcasecmp(property, n) == 0
|
||||
#define VALUE_IS(v) strcasecmp(value, v) == 0
|
||||
|
||||
static int config_handler(unsigned lineno, const char* section, const char* property, char* value)
|
||||
{
|
||||
if(SECTION_IS("") || SECTION_IS("macro")) {
|
||||
if(PROPERTY_IS("slicer")
|
||||
|| PROPERTY_IS("filament")
|
||||
|| PROPERTY_IS("start")
|
||||
|| PROPERTY_IS("pause")
|
||||
|| PROPERTY_IS("temp")
|
||||
|| PROPERTY_IS("temperature")) {
|
||||
parse_macro(property, value);
|
||||
}
|
||||
else goto SECTION_ERROR;
|
||||
}
|
||||
// set the temperature of selected tool to active (if active is different to standby)
|
||||
if(override[selectedExtruder].active_temperature
|
||||
&& override[selectedExtruder].active_temperature != tool[selectedExtruder].nozzle_temperature) {
|
||||
unsigned temperature = override[selectedExtruder].active_temperature;
|
||||
set_nozzle_temperature(selectedExtruder, temperature);
|
||||
tool[selectedExtruder].nozzle_temperature = temperature;
|
||||
// wait for nozzle to head up
|
||||
wait_for_extruder(selectedExtruder, timeout);
|
||||
else if(SECTION_IS("printer")) {
|
||||
if(PROPERTY_IS("ditto_printing")) dittoPrinting = atoi(value);
|
||||
else if(PROPERTY_IS("build_progress")) buildProgress = atoi(value);
|
||||
else if(PROPERTY_IS("nominal_filament_diameter")
|
||||
|| PROPERTY_IS("slicer_filament_diameter")) machine.nominal_filament_diameter = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("machine_type")) {
|
||||
// use on-board machine definition
|
||||
if(VALUE_IS("c3")) machine = cupcake_G3;
|
||||
else if(VALUE_IS("c4")) machine = cupcake_G4;
|
||||
else if(VALUE_IS("cp4")) machine = cupcake_P4;
|
||||
else if(VALUE_IS("cpp")) machine = cupcake_PP;
|
||||
else if(VALUE_IS("t7")) machine = thing_o_matic_7;
|
||||
else if(VALUE_IS("t6")) machine = thing_o_matic_7;
|
||||
else if(VALUE_IS("t7")) machine = thing_o_matic_7;
|
||||
else if(VALUE_IS("t7d")) machine = thing_o_matic_7D;
|
||||
else if(VALUE_IS("r1")) machine = replicator_1;
|
||||
else if(VALUE_IS("r1d")) machine = replicator_1D;
|
||||
else if(VALUE_IS("r2")) machine = replicator_2;
|
||||
else if(VALUE_IS("r2x")) machine = replicator_2X;
|
||||
else {
|
||||
fprintf(stderr, "(line %u) Configuration error: unrecognised machine type '%s'" EOL, lineno, value);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if(PROPERTY_IS("build_platform_temperature")) {
|
||||
if(machine.a.has_heated_build_platform) override[A].build_platform_temperature = atoi(value);
|
||||
else if(machine.b.has_heated_build_platform) override[B].build_platform_temperature = atoi(value);
|
||||
}
|
||||
else if(PROPERTY_IS("sd_card_path")) {
|
||||
sdCardPath = strdup(value);
|
||||
}
|
||||
else goto SECTION_ERROR;
|
||||
}
|
||||
// switch any active G10 offset (G54 or G55)
|
||||
if(currentOffset == currentExtruder + 1) {
|
||||
currentOffset = selectedExtruder + 1;
|
||||
else if(SECTION_IS("x")) {
|
||||
if(PROPERTY_IS("max_feedrate")) machine.x.max_feedrate = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("home_feedrate")) machine.x.home_feedrate = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("steps_per_mm")) machine.x.steps_per_mm = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("endstop")) machine.x.endstop = atoi(value);
|
||||
else goto SECTION_ERROR;
|
||||
}
|
||||
// change current toolhead in order to apply the calibration offset
|
||||
change_extruder_offset(selectedExtruder);
|
||||
// set current extruder so changes in E are expressed as changes to A or B
|
||||
currentExtruder = selectedExtruder;
|
||||
else if(SECTION_IS("y")) {
|
||||
if(PROPERTY_IS("max_feedrate")) machine.y.max_feedrate = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("home_feedrate")) machine.y.home_feedrate = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("steps_per_mm")) machine.y.steps_per_mm = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("endstop")) machine.y.endstop = atoi(value);
|
||||
else goto SECTION_ERROR;
|
||||
}
|
||||
else if(SECTION_IS("z")) {
|
||||
if(PROPERTY_IS("max_feedrate")) machine.z.max_feedrate = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("home_feedrate")) machine.z.home_feedrate = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("steps_per_mm")) machine.z.steps_per_mm = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("endstop")) machine.z.endstop = atoi(value);
|
||||
else goto SECTION_ERROR;
|
||||
}
|
||||
else if(SECTION_IS("a")) {
|
||||
if(PROPERTY_IS("max_feedrate")) machine.a.max_feedrate = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("steps_per_mm")) machine.a.steps_per_mm = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("motor_steps")) machine.a.motor_steps = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("has_heated_build_platform")) machine.a.has_heated_build_platform = atoi(value);
|
||||
else goto SECTION_ERROR;
|
||||
}
|
||||
else if(SECTION_IS("right")) {
|
||||
if(PROPERTY_IS("active_temperature")
|
||||
|| PROPERTY_IS("nozzle_temperature")) override[A].active_temperature = atoi(value);
|
||||
else if(PROPERTY_IS("standby_temperature")) override[A].standby_temperature = atoi(value);
|
||||
else if(PROPERTY_IS("build_platform_temperature")) override[A].build_platform_temperature = atoi(value);
|
||||
else if(PROPERTY_IS("actual_filament_diameter")) override[A].actual_filament_diameter = strtod(value, NULL);
|
||||
else goto SECTION_ERROR;
|
||||
}
|
||||
else if(SECTION_IS("b")) {
|
||||
if(PROPERTY_IS("max_feedrate")) machine.b.max_feedrate = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("steps_per_mm")) machine.b.steps_per_mm = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("motor_steps")) machine.b.motor_steps = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("has_heated_build_platform")) machine.b.has_heated_build_platform = atoi(value);
|
||||
else goto SECTION_ERROR;
|
||||
}
|
||||
else if(SECTION_IS("left")) {
|
||||
if(PROPERTY_IS("active_temperature")
|
||||
|| PROPERTY_IS("nozzle_temperature")) override[B].active_temperature = atoi(value);
|
||||
else if(PROPERTY_IS("standby_temperature")) override[B].standby_temperature = atoi(value);
|
||||
else if(PROPERTY_IS("build_platform_temperature")) override[B].build_platform_temperature = atoi(value);
|
||||
else if(PROPERTY_IS("actual_filament_diameter")) override[B].actual_filament_diameter = strtod(value, NULL);
|
||||
else goto SECTION_ERROR;
|
||||
}
|
||||
else if(SECTION_IS("machine")) {
|
||||
if(PROPERTY_IS("nominal_filament_diameter")
|
||||
|| PROPERTY_IS("slicer_filament_diameter")) machine.nominal_filament_diameter = strtod(value, NULL);
|
||||
else if(PROPERTY_IS("extruder_count")) machine.extruder_count = atoi(value);
|
||||
else if(PROPERTY_IS("timeout")) machine.timeout = atoi(value);
|
||||
else goto SECTION_ERROR;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "(line %u) Configuration error: unrecognised section [%s]" EOL, lineno, section);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
SECTION_ERROR:
|
||||
fprintf(stderr, "(line %u) Configuration error: [%s] section contains unrecognised property %s=..." EOL, lineno, section, property);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// display usage and exit
|
||||
|
@ -1908,7 +2008,7 @@ void do_tool_change(int timeout) {
|
|||
static void usage()
|
||||
{
|
||||
fputs("GPX " GPX_VERSION " Copyright (c) 2013 WHPThomas, All rights reserved." EOL, stderr);
|
||||
fputs(EOL "Usage: gpx [-ps] [-m <MACHINE>] [-c <CONFIG>] INPUT [OUTPUT]" EOL, stderr);
|
||||
fputs(EOL "Usage: gpx [-ps] [-m <MACHINE>] [-c <CONFIG>] <INPUT> [<OUTPUT>]" EOL, stderr);
|
||||
fputs(EOL "Switches:" EOL EOL, stderr);
|
||||
fputs("\t-p\toverride build percentage" EOL, stderr);
|
||||
fputs("\t-s\tenable stdin and stdout support for command pipes" EOL, stderr);
|
||||
|
@ -1946,25 +2046,18 @@ int main(int argc, char * argv[])
|
|||
int command_emitted = 0;
|
||||
int do_pause_at_zpos = 0;
|
||||
int standard_io = 0;
|
||||
char *config = NULL;
|
||||
|
||||
initialize_globals();
|
||||
|
||||
// READ COMMAND LINE
|
||||
|
||||
// get the command line options
|
||||
while ((c = getopt(argc, argv, "c:m:ps")) != -1) {
|
||||
while ((c = getopt(argc, argv, "psm:c:")) != -1) {
|
||||
command_emitted++;
|
||||
switch (c) {
|
||||
case 'c':
|
||||
i = ini_parse(optarg, config_handler, NULL);
|
||||
if (i < 0) {
|
||||
fprintf(stderr, "Command line error: cannot load custom machine definition '%s'" EOL, optarg);
|
||||
usage();
|
||||
}
|
||||
else if (i > 0) {
|
||||
fprintf(stderr, "(line %u) Condifuration syntax error: unrecognised paremeters" EOL, i);
|
||||
usage();
|
||||
}
|
||||
config = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
if(strcasecmp(optarg, "c3") == 0) machine = cupcake_G3;
|
||||
|
@ -2016,30 +2109,13 @@ int main(int argc, char * argv[])
|
|||
*filename++ = 'i';
|
||||
*filename++ = '\0';
|
||||
filename = buffer;
|
||||
i = ini_parse(filename, config_handler, NULL);
|
||||
i = ini_parse(filename, config_handler);
|
||||
if (i > 0) {
|
||||
fprintf(stderr, "(line %u) Condifuration syntax error in gpx.ini: unrecognised paremeters" EOL, i);
|
||||
fprintf(stderr, "(line %u) Configuration syntax error in gpx.ini: unrecognised paremeters" EOL, i);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if(dittoPrinting && machine.extruder_count == 1) {
|
||||
fputs("Configuration error: ditto printing cannot access non-existant second extruder" EOL, stderr);
|
||||
dittoPrinting = 0;
|
||||
}
|
||||
|
||||
// CALCULATE FILAMENT SCALING
|
||||
|
||||
if(override[A].actual_filament_diameter > 0.0001
|
||||
&& override[A].actual_filament_diameter != machine.nominal_filament_diameter) {
|
||||
set_filament_scale(A, override[A].actual_filament_diameter);
|
||||
}
|
||||
|
||||
if(override[B].actual_filament_diameter > 0.0001
|
||||
&& override[B].actual_filament_diameter != machine.nominal_filament_diameter) {
|
||||
set_filament_scale(B, override[B].actual_filament_diameter);
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
|
@ -2104,6 +2180,37 @@ int main(int argc, char * argv[])
|
|||
usage();
|
||||
}
|
||||
|
||||
// READ CONFIGURATION
|
||||
|
||||
if(config) {
|
||||
i = ini_parse(config, config_handler);
|
||||
if (i < 0) {
|
||||
fprintf(stderr, "Command line error: cannot load configuration file '%s'" EOL, config);
|
||||
usage();
|
||||
}
|
||||
else if (i > 0) {
|
||||
fprintf(stderr, "(line %u) Configuration syntax error in %s: unrecognised paremeters" EOL, i, config);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if(dittoPrinting && machine.extruder_count == 1) {
|
||||
fputs("Configuration error: ditto printing cannot access non-existant second extruder" EOL, stderr);
|
||||
dittoPrinting = 0;
|
||||
}
|
||||
|
||||
// CALCULATE FILAMENT SCALING
|
||||
|
||||
if(override[A].actual_filament_diameter > 0.0001
|
||||
&& override[A].actual_filament_diameter != machine.nominal_filament_diameter) {
|
||||
set_filament_scale(A, override[A].actual_filament_diameter);
|
||||
}
|
||||
|
||||
if(override[B].actual_filament_diameter > 0.0001
|
||||
&& override[B].actual_filament_diameter != machine.nominal_filament_diameter) {
|
||||
set_filament_scale(B, override[B].actual_filament_diameter);
|
||||
}
|
||||
|
||||
// READ INPUT AND CONVERT TO OUTPUT
|
||||
|
||||
// at this point we have read the command line, set the machine definition
|
||||
|
@ -2237,7 +2344,15 @@ int main(int argc, char * argv[])
|
|||
}
|
||||
else if(*p == ';') {
|
||||
if(*(p + 1) == '@') {
|
||||
parse_macro(normalize_comment(p + 2));
|
||||
char *s = p + 2;
|
||||
if(isalpha(*s)) {
|
||||
char *macro = s;
|
||||
// skip any no space characters
|
||||
while(*s && !isspace(*s)) s++;
|
||||
// null terminate
|
||||
if(*s) *s++ = 0;
|
||||
parse_macro(macro, normalize_comment(s));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Comment
|
||||
|
@ -2577,6 +2692,10 @@ int main(int argc, char * argv[])
|
|||
wait_for_build_platform(B, timeout);
|
||||
command_emitted++;
|
||||
}
|
||||
if(pausePending) {
|
||||
pause_at_zpos(commandAt[0].z);
|
||||
}
|
||||
atTemperature = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2933,8 +3052,7 @@ int main(int argc, char * argv[])
|
|||
pause_at_zpos(z);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "(line %u) Syntax warning: M322 is missing Z axes, assuming zero (0)" EOL, lineNumber);
|
||||
pause_at_zpos(0.0);
|
||||
fprintf(stderr, "(line %u) Syntax warning: M322 is missing Z axis" EOL, lineNumber);
|
||||
}
|
||||
command_emitted++;
|
||||
break;
|
||||
|
@ -2976,7 +3094,7 @@ int main(int argc, char * argv[])
|
|||
}
|
||||
// check for pending pause @ zPos
|
||||
if(do_pause_at_zpos) {
|
||||
pause_at_zpos(pauseAt[pauseAtIndex].z);
|
||||
pause_at_zpos(commandAt[commandAtIndex].z);
|
||||
do_pause_at_zpos = 0;
|
||||
}
|
||||
// update progress
|
||||
|
|
9
gpx.h
9
gpx.h
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include <limits.h>
|
||||
|
||||
#define GPX_VERSION "1.0 (RC1)"
|
||||
#define GPX_VERSION "1.0 (RC2)"
|
||||
|
||||
/* Nonzero to 'simulate' RPM using 5D, zero to disable */
|
||||
|
||||
|
@ -185,11 +185,12 @@ typedef struct tFilament {
|
|||
|
||||
#define FILAMENT_MAX 32
|
||||
|
||||
typedef struct tPauseAt {
|
||||
typedef struct tCommandAt {
|
||||
double z;
|
||||
unsigned filament_index;
|
||||
} PauseAt;
|
||||
unsigned temperature;
|
||||
} CommandAt;
|
||||
|
||||
#define PAUSE_AT_MAX 64
|
||||
#define COMMAND_AT_MAX 128
|
||||
|
||||
#endif
|
||||
|
|
19
gpx.ini
19
gpx.ini
|
@ -9,11 +9,20 @@
|
|||
[printer]
|
||||
|
||||
; specify the machine definition using a pre-defined built-in type identifier
|
||||
; NOTE: settings are order dependnet, so always start with this settng
|
||||
; r1 = Replicator 1 single
|
||||
; r1d = Replicator 1 dual
|
||||
; r2 = Replicator 2 (default)
|
||||
; r2x = Replicator 2X
|
||||
;
|
||||
; NOTE: settings are order dependnet, so always start by settng the machine type
|
||||
;
|
||||
; c3 = Cupcake Gen3 XYZ, Mk5/6 + Gen4 Extruder
|
||||
; c4 = Cupcake Gen4 XYZ, Mk5/6 + Gen4 Extruder
|
||||
; cp4 = Cupcake Pololu XYZ, Mk5/6 + Gen4 Extruder
|
||||
; cpp = Cupcake Pololu XYZ, Mk5/6 + Pololu Extruder
|
||||
; t6 = TOM Mk6 - single extruder
|
||||
; t7 = TOM Mk7 - single extruder
|
||||
; t7d = TOM Mk7 - dual extruder
|
||||
; r1 = Replicator 1 - single extruder
|
||||
; r1d = Replicator 1 - dual extruder
|
||||
; r2 = Replicator 2 (default config)
|
||||
; r2x = Replicator 2X
|
||||
|
||||
machine_type=r2
|
||||
|
||||
|
|
14
ini.c
14
ini.c
|
@ -60,9 +60,8 @@ static char* strncpy0(char* dest, const char* src, size_t size)
|
|||
|
||||
/* See documentation in header file. */
|
||||
int ini_parse_file(FILE* file,
|
||||
int (*handler)(void*, const char*, const char*,
|
||||
const char*),
|
||||
void* user)
|
||||
int (*handler)(unsigned, const char*, const char*,
|
||||
char*))
|
||||
{
|
||||
/* Uses a fair bit of stack (use heap instead if you need to) */
|
||||
#if INI_USE_STACK
|
||||
|
@ -108,7 +107,7 @@ int ini_parse_file(FILE* file,
|
|||
else if (*prev_name && *start && start > line) {
|
||||
/* Non-black line with leading whitespace, treat as continuation
|
||||
of previous name's value (as per Python ConfigParser). */
|
||||
if (!handler(user, section, prev_name, start) && !error)
|
||||
if (!handler(lineno, section, prev_name, start) && !error)
|
||||
error = lineno;
|
||||
}
|
||||
#endif
|
||||
|
@ -142,7 +141,7 @@ int ini_parse_file(FILE* file,
|
|||
|
||||
/* Valid name[=:]value pair found, call handler */
|
||||
strncpy0(prev_name, name, sizeof(prev_name));
|
||||
if (!handler(user, section, name, value) && !error)
|
||||
if (!handler(lineno, section, name, value) && !error)
|
||||
error = lineno;
|
||||
}
|
||||
else if (!error) {
|
||||
|
@ -161,8 +160,7 @@ int ini_parse_file(FILE* file,
|
|||
|
||||
/* See documentation in header file. */
|
||||
int ini_parse(const char* filename,
|
||||
int (*handler)(void*, const char*, const char*, const char*),
|
||||
void* user)
|
||||
int (*handler)(unsigned, const char*, const char*, char*))
|
||||
{
|
||||
FILE* file;
|
||||
int error;
|
||||
|
@ -170,7 +168,7 @@ int ini_parse(const char* filename,
|
|||
file = fopen(filename, "r");
|
||||
if (!file)
|
||||
return -1;
|
||||
error = ini_parse_file(file, handler, user);
|
||||
error = ini_parse_file(file, handler);
|
||||
fclose(file);
|
||||
return error;
|
||||
}
|
||||
|
|
10
ini.h
10
ini.h
|
@ -31,16 +31,14 @@ extern "C" {
|
|||
error (only when INI_USE_STACK is zero).
|
||||
*/
|
||||
int ini_parse(const char* filename,
|
||||
int (*handler)(void* user, const char* section,
|
||||
const char* name, const char* value),
|
||||
void* user);
|
||||
int (*handler)(unsigned lineno, const char* section,
|
||||
const char* name, char* value));
|
||||
|
||||
/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
|
||||
close the file when it's finished -- the caller must do that. */
|
||||
int ini_parse_file(FILE* file,
|
||||
int (*handler)(void* user, const char* section,
|
||||
const char* name, const char* value),
|
||||
void* user);
|
||||
int (*handler)(unsigned lineno, const char* section,
|
||||
const char* name, char* value));
|
||||
|
||||
/* Nonzero to allow multi-line value parsing, in the style of Python's
|
||||
ConfigParser. If allowed, ini_parse() will call the handler with the same
|
||||
|
|
Loading…
Reference in New Issue