Changed calculator to use physics simulation

This commit is contained in:
DocWibbleyWobbley 2023-06-22 17:32:09 +03:00
parent 62d379fd3b
commit 24f16d2491
9 changed files with 25338 additions and 208 deletions

View File

@ -1,2 +1,2 @@
all:
g++ -std=c++11 gcode.cpp main.cpp Point.cpp -o gcode_time
g++ -std=c++11 gcode.cpp main.cpp Point.cpp TimeCalc.cpp -o gcode_time

View File

@ -1,6 +1,10 @@
# Gcode Estimator
C/C++ Gcode Estimator
# Credits
JSON Library Used - https://github.com/nlohmann/json
v3.11.2
### Prerequisites
`g++ make`
@ -8,12 +12,18 @@ C/C++ Gcode Estimator
1. Go to the directory
2. Execute `make`
### Settings
* Use as is to get linear calculations for time
* Copy `config_example.json` to `config.json` and edit based on your printer settings
### Usage
`./gcode_time [file]`
`./gcode_time [file] ...`
**file** - a file containing gcode
### Example output
`Estimation - 05:20:10`
`Estimation - 05:20:10`
`Adding 10% - 05:52:11`
`Adding 10% - 05:52:11`
`Removing 10% - 04:48:09`

468
TimeCalc.cpp Normal file
View File

@ -0,0 +1,468 @@
// 1. Dx Dy Dz De; e_total_offset += De;
// 2. m = sqrt(Dx * Dx + Dy * Dy + Dz * Dz)
// 3. Dx /= m; Dy /= m; Dz /= m; De /= m;
// 4. V = min(speed, Vmax_x / Dx, Vmax_y / Dy, Vmax_z / Dz, Vmax_e / De);
// 5. A = min(Amax_x / Dx, Amax_y / Dy, Amax_z / Dz, Amax_e / De);
// 6. Vx = V * Dx; Vy = V * Dy; Vz = V * Dz; Ve = V * De;
// 6.1 Vend_prev_x = Vx; ... -> Calculate prev move and wait for current Vend
// 7. Ax = A * Dx; Ay = A * Dy; Az = A * Dz; Ae = A * De;
// 8. time = max(calc_time_complex(x), ...(y), ...(z), ...(e))
#include "TimeCalc.h"
#define DEBUG_CALC 0
#include <limits>
#include "math.h"
#include <iostream>
using namespace std;
static double vector_min(const vector<double>& vec)
{
double min;
int idx;
if (vec.empty())
{
return 0.0;
}
idx = 0;
min = abs(vec[0]);
for (int i = 1; i < vec.size(); ++i)
{
if (abs(vec[i]) < min)
{
min = abs(vec[i]);
idx = i;
}
}
return vec[idx];
}
static double vector_max(const vector<double>& vec)
{
double max;
int idx;
if (vec.empty())
{
return 0.0;
}
idx = 0;
max = abs(vec[0]);
for (int i = 1; i < vec.size(); ++i)
{
if (abs(vec[i]) > max)
{
idx = i;
max = abs(vec[i]);
}
}
return vec[idx];
}
static double calc_dist(double vel, double accel, double t)
{
return vel * t + 0.5 * accel * t * t;
}
static double calc_time_to_accel(double accel, double vel_start, double vel_end)
{
return abs((vel_start - vel_end) / accel);
}
// Triangle Velocity
static double calc_time_very_complex(double dist, double vel_start, double vel_end, double accel)
{
double a;
double b;
double c;
double d;
double val[2];
double res = 0;
if (accel == 0)
{
return 0;
}
a = accel;
b = 2 * vel_end;
c = (vel_end * vel_end - vel_start * vel_start)/(2 * accel) - dist;
d = b * b - 4 * a * c;
d = sqrt(d);
val[0] = (-b + d)/(2*a);
val[1] = (-b - d)/(2*a);
if (val[0] >= 0)
{
res = val[0];
}
if (val[1] >= 0)
{
res = val[1];
}
return (2 * res + (vel_end - vel_start) / accel);
}
static double calc_time_complex(double dist, double accel, double max_vel_change, double vel_start, double vel_end, double vel_max_target)
{
double result = 0.0;
double accel_time;
double accel_dist;
double deccel_time;
double deccel_dist;
if (dist == 0)
{
return 0;
}
if (accel == 0)
{
// Linear calculation - It's something
return dist/vel_max_target;
}
// "Instant" velocity change on <= "Jerk"
if (vel_max_target != vel_start)
{
if (abs(vel_max_target - vel_start) <= max_vel_change)
{
vel_start = vel_max_target;
}
}
// "Instant" velocity change on <= "Jerk"
if (vel_max_target != vel_end)
{
if (abs(vel_max_target - vel_end) <= max_vel_change)
{
vel_end = vel_max_target;
}
}
accel_time = calc_time_to_accel(accel, vel_start, vel_max_target);
accel_dist = calc_dist(vel_start, accel, accel_time);
deccel_time = calc_time_to_accel(accel, vel_max_target, vel_end);
deccel_dist = calc_dist(vel_max_target, -accel, deccel_time);
// Triangle Velocity
if (abs(accel_dist + deccel_dist) > abs(dist))
{
result = calc_time_very_complex(dist, vel_start, vel_end, accel);
// Something's fucky
if (0 == result)
{
// Linear calculation - It's something
return abs(dist/vel_max_target);
}
}
// Trapezoid Velocity
else
{
dist -= (accel_dist + deccel_dist);
result += (accel_time + deccel_time);
result += abs(dist / vel_max_target);
}
return result;
}
TimeCalc::PrinterMove::PrinterMove()
: dist(0.0)
{
fill_n(delta, AXIS_COUNT, 0.0);
fill_n(unit, AXIS_COUNT, 0.0);
fill_n(vel, AXIS_COUNT, 0.0);
fill_n(accel, AXIS_COUNT, 0.0);
fill_n(vel_start, AXIS_COUNT, 0.0);
fill_n(vel_end, AXIS_COUNT, 0.0);
}
TimeCalc::TimeCalc()
: m_time(0.0)
{
reset();
}
void TimeCalc::reset()
{
m_time = 0.0;
fill_n(m_extruder_length, EXTRUDER_COUNT, 0.0);
fill_n(m_pos, AXIS_COUNT, 0.0);
fill_n(m_accel_max, AXIS_COUNT, 0.0);
fill_n(m_vel_max, AXIS_COUNT, 0.0);
fill_n(m_jerk_max, AXIS_COUNT, 0.0);
m_moves.clear();
}
void TimeCalc::add_move(Point new_pos, double speed)
{
PrinterMove move_new;
vector<double> temp;
Point pos_temp;
double pos_new[AXIS_COUNT];
double vel;
double accel;
double prev_move_idx;
static int counter = 0;
pos_new[0] = new_pos.x;
pos_new[1] = new_pos.y;
pos_new[2] = new_pos.z;
pos_new[3] = new_pos.e;
pos_temp = Point(m_pos[0], m_pos[1], m_pos[2], m_pos[3]);
move_new.dist = new_pos.get_dist(pos_temp);
#if DEBUG_CALC
cout << "---" << endl;
cout << "Dist - " << move_new.dist << endl;
#endif
if (0.0 == move_new.dist)
{
return;
}
// Calculate Delta And Unit Vector
for (int i = 0 ; i < AXIS_COUNT; ++i)
{
move_new.delta[i] = pos_new[i] - m_pos[i];
move_new.unit[i] = move_new.delta[i] / move_new.dist;
#if DEBUG_CALC
cout << "Unit [" << i << "] - " << move_new.unit[i] << endl;
#endif
}
// Calculate velocity
temp.clear();
temp.push_back(speed);
for (int i = 0 ; i < AXIS_COUNT; ++i)
{
if (0.0 != move_new.unit[i] && 0.0 != m_vel_max[i])
{
temp.push_back(m_vel_max[i] / move_new.unit[i]);
}
}
vel = abs(vector_min(temp));
#if DEBUG_CALC
cout << "Vel - " << vel << endl;
#endif
// Calculate acceleration
temp.clear();
for (int i = 0 ; i < AXIS_COUNT; ++i)
{
if (0.0 != move_new.unit[i] && 0.0 != m_accel_max[i])
{
temp.push_back(m_accel_max[i] / move_new.unit[i]);
}
}
accel = abs(vector_min(temp));
#if DEBUG_CALC
cout << "Accel - " << accel << endl;
#endif
// Calculate Component Velocity and Acceleration
for (int i = 0 ; i < AXIS_COUNT; ++i)
{
move_new.vel[i] = vel * move_new.unit[i];
move_new.accel[i] = accel * move_new.unit[i];
}
// Calculate veclocities for/from previous move
if (!m_moves.empty())
{
prev_move_idx = m_moves.size() - 1;
for (int i = 0; i < AXIS_COUNT; ++i)
{
// If we're changing direction
if (m_moves[prev_move_idx].vel[i] * move_new.vel[i] < 0)
{
m_moves[prev_move_idx].vel_end[i] = 0.0;
}
else
{
// If we're accelerating
if (abs(m_moves[prev_move_idx].vel[i]) < abs(move_new.vel[i]))
{
m_moves[prev_move_idx].vel_end[i] = m_moves[prev_move_idx].vel[i];
}
else
{
m_moves[prev_move_idx].vel_end[i] = move_new.vel[i];
}
}
}
// Calc end velocity for prev move
temp.clear();
for (int i = 0; i < AXIS_COUNT; ++i)
{
if (0.0 != m_moves[prev_move_idx].unit[i])
{
temp.push_back(m_moves[prev_move_idx].vel_end[i] / m_moves[prev_move_idx].unit[i]);
}
}
vel = vector_min(temp);
for (int i = 0; i < AXIS_COUNT; ++i)
{
m_moves[prev_move_idx].vel_end[i] = vel * m_moves[prev_move_idx].unit[i];
move_new.vel_start[i] = m_moves[prev_move_idx].vel_end[i];
#if DEBUG_CALC
cout << "Vel Start [" << i << "] - " << m_moves[prev_move_idx].vel_end[i] << endl;
#endif
}
// Do a move calculation
flush();
}
m_moves.push_back(move_new);
for (int i = 0; i < AXIS_COUNT; ++i)
{
m_pos[i] = pos_new[i];
}
}
void TimeCalc::set_pos(Point new_pos)
{
flush();
if (new_pos.e != m_pos[3])
{
m_extruder_length[0] += m_pos[3];
m_extruder_length[0] -= new_pos.e;
}
m_pos[0] = new_pos.x;
m_pos[1] = new_pos.y;
m_pos[2] = new_pos.z;
m_pos[3] = new_pos.e;
}
void TimeCalc::flush()
{
vector<double> times;
double max;
for (PrinterMove& move : m_moves)
{
// Find the slowest axis and add it to the total time
times.clear();
for (int i = 0; i < AXIS_COUNT; ++i)
{
times.push_back(calc_time_complex(move.delta[i], move.accel[i],
m_jerk_max[i], move.vel_start[i], move.vel_end[i], move.vel[i]));
}
max = vector_max(times);
if (max < 0)
{
printf("Dist - %10.5f - %10.5f\n", move.dist, max);
for (int i = 0; i < AXIS_COUNT; ++i)
{
printf("Delta [%d] - %10.5f\n", i, move.delta[i]);
}
for (int i = 0; i < AXIS_COUNT; ++i)
{
printf("Unit [%d] - %10.5f\n", i, move.unit[i]);
}
for (int i = 0; i < AXIS_COUNT; ++i)
{
printf("V0 [%d] - %10.5f\n", i, move.vel_start[i]);
}
for (int i = 0; i < AXIS_COUNT; ++i)
{
printf("Vel [%d] - %10.5f\n", i, move.vel[i]);
}
for (int i = 0; i < AXIS_COUNT; ++i)
{
printf("V2 [%d] - %10.5f\n", i, move.vel_end[i]);
}
for (int i = 0; i < AXIS_COUNT; ++i)
{
printf("Accel [%d] - %10.5f\n", i, move.accel[i]);
}
}
m_time += max;
}
m_moves.clear();
}
void TimeCalc::add_time(double time)
{
m_time += time;
}
double TimeCalc::get_time() const
{
return m_time;
}
double TimeCalc::get_extruder_length(int idx) const
{
if (idx >= EXTRUDER_COUNT)
{
return 0.0;
}
return m_extruder_length[idx] + m_pos[3 + idx];
}
Point TimeCalc::get_pos() const
{
return Point(m_pos[0], m_pos[1], m_pos[2], m_pos[3]);
}
void TimeCalc::set_max_acceleration(int axis, double value)
{
if ((axis > 0) && (axis < AXIS_COUNT))
{
m_accel_max[axis] = value;
}
}
void TimeCalc::set_max_velocity(int axis, double value)
{
if ((axis > 0) && (axis < AXIS_COUNT))
{
m_vel_max[axis] = value;
}
}
void TimeCalc::set_max_jerk(int axis, double value)
{
if ((axis > 0) && (axis < AXIS_COUNT))
{
m_jerk_max[axis] = value;
}
}

56
TimeCalc.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef TIMECALC_H_
#define TIMECALC_H_
#include <algorithm>
#include <vector>
#include "Point.h"
#define EXTRUDER_COUNT 1
#define AXIS_COUNT (3 + EXTRUDER_COUNT)
class TimeCalc
{
public:
struct PrinterMove
{
PrinterMove();
double dist;
double delta[AXIS_COUNT];
double unit[AXIS_COUNT];
double vel[AXIS_COUNT];
double accel[AXIS_COUNT];
double vel_start[AXIS_COUNT];
double vel_end[AXIS_COUNT];
};
private:
double m_extruder_length[EXTRUDER_COUNT];
double m_time;
double m_pos[AXIS_COUNT];
double m_accel_max[AXIS_COUNT];
double m_vel_max[AXIS_COUNT];
double m_jerk_max[AXIS_COUNT];
std::vector<PrinterMove> m_moves;
public:
TimeCalc();
void reset();
void add_move(Point new_pos, double speed);
void set_pos(Point new_pos);
void flush();
void add_time(double time);
double get_time() const;
double get_extruder_length(int idx) const;
Point get_pos() const;
void set_max_acceleration(int axis, double value);
void set_max_velocity(int axis, double value);
void set_max_jerk(int axis, double value);
};
#endif // TIMECALC_H_

28
config_example.json Normal file
View File

@ -0,0 +1,28 @@
{
"x":
{
"acceleration": 500,
"velocity": 500,
"jerk": 10
},
"y":
{
"acceleration": 500,
"velocity": 500,
"jerk": 10
},
"z":
{
"acceleration": 100,
"velocity": 5,
"jerk": 0.4
},
"extruders":
[
{
"acceleration": 500,
"velocity": 50,
"jerk": 5
}
]
}

165
gcode.cpp
View File

@ -37,16 +37,21 @@ pair<char, double> extract_argument(const string& str)
return result;
}
void gcode_dummy(const vector<string>&, TimeCalc&, double&)
{
}
// Linear Move
double g1(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
void g1(const vector<string>& line_tokens, TimeCalc& calc, double& speed)
{
double result;
vector<string>::const_iterator it;
pair<char, double> arg;
Point end;
Point pos = calc.get_pos();
Point pos_old = pos;
double distance;
static int counter = 1;
end = pos;
it = line_tokens.begin();
for (++it; it != line_tokens.end(); ++it)
{
@ -56,28 +61,34 @@ double g1(const vector<string>& line_tokens, Point& pos, double& speed, double&
{
// Extruder
case 'E':
end.e = arg.second;
case 'e':
pos.e = arg.second;
break;
// Feedrate (Speed) in units/min
case 'F':
case 'f':
speed = arg.second / 60;
break;
// Laser power
case 'S':
case 's':
break;
case 'X':
end.x = arg.second;
case 'x':
pos.x = arg.second;
break;
case 'Y':
end.y = arg.second;
case 'y':
pos.y = arg.second;
break;
case 'Z':
end.z = arg.second;
case 'z':
pos.z = arg.second;
break;
default:
@ -86,45 +97,11 @@ double g1(const vector<string>& line_tokens, Point& pos, double& speed, double&
}
}
#if DEBUG
for (vector<string>::const_iterator it = line_tokens.begin(); it != line_tokens.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
cout << "Old pos - ";
pos.print();
cout << endl;
cout << "New pos - ";
end.print();
cout << endl;
#endif // DEBUG
result = 0;
// Perform time calc
distance = pos.get_dist(end);
#if DEBUG
cout << "Distance - " << distance << endl;
cout << "Speed - " << speed << endl;
#endif
if (0 != speed)
{
result = distance / speed;
}
// Our new position
pos = end;
#if DEBUG
cout << "Time - " << result << endl << endl;
#endif // DEBUG
return result;
calc.add_move(pos, speed);
}
// Dwell
double g4(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
void g4(const vector<string>& line_tokens, TimeCalc& calc, double& speed)
{
double result;
vector<string>::const_iterator it;
@ -140,11 +117,13 @@ double g4(const vector<string>& line_tokens, Point& pos, double& speed, double&
{
// P is for miliseconds
case 'P':
case 'p':
result += arg.second / 1000;
break;
// S is for seconds
case 'S':
case 's':
result += arg.second;
break;
@ -154,43 +133,27 @@ double g4(const vector<string>& line_tokens, Point& pos, double& speed, double&
}
}
#if DEBUG
for (vector<string>::const_iterator it = line_tokens.begin(); it != line_tokens.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
cout << "Time - " << result << endl << endl;
#endif // DEBUG
return result;
}
// Set Units to Milimeters
double g21(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
{
return 0;
calc.add_time(result);
}
// Move to Origin (Home)
double g28(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
void g28(const vector<string>& line_tokens, TimeCalc& calc, double& speed)
{
// Used only at beginning or end so not relevant
return 0;
}
Point pos = calc.get_pos();
// Set to Absolute Positioning
double g90(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
{
return 0;
pos.x = 0;
pos.y = 0;
pos.z = 0;
calc.set_pos(pos);
}
// Set Position
double g92(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
void g92(const vector<string>& line_tokens, TimeCalc& calc, double& speed)
{
vector<string>::const_iterator it;
pair<char, double> arg;
Point pos = calc.get_pos();
#if DEBUG
for (vector<string>::const_iterator it = line_tokens.begin(); it != line_tokens.end(); ++it)
@ -212,20 +175,22 @@ double g92(const vector<string>& line_tokens, Point& pos, double& speed, double&
switch (arg.first)
{
case 'E':
e_total_offset += pos.e;
e_total_offset -= arg.second;
case 'e':
pos.e = arg.second;
break;
case 'X':
case 'x':
pos.x = arg.second;
break;
case 'Y':
case 'y':
pos.y = arg.second;
break;
case 'Z':
case 'z':
pos.z = arg.second;
break;
@ -242,61 +207,5 @@ double g92(const vector<string>& line_tokens, Point& pos, double& speed, double&
#endif // DEBUG
// There's no actual movement
return 0;
}
// Set extruder to absolute mode
double m82(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
{
return 0;
}
// Stop idle hold
double m84(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
{
return 0;
}
// Set Extruder Temperature
double m104(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
{
return 0;
}
// Fan On
double m106(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
{
return 0;
}
// Fan Off
double m107(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
{
return 0;
}
// Set Extruder Temperature and Wait
double m109(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
{
// Assume everything is preheated
return 0;
}
// Display Message
double m117(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
{
return 0;
}
// Set Bed Temperature (Fast)
double m140(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
{
return 0;
}
// Wait for bed temperature to reach target temp
double m190(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset)
{
// Assume everything is preheated
return 0;
calc.set_pos(pos);
}

27
gcode.h
View File

@ -5,28 +5,21 @@
#include <string>
#include "Point.h"
#include "TimeCalc.h"
using namespace std;
// Typedef of the function pointer
typedef double (*gcode_cmd_t)(const vector<string>&, Point&, double&, double&);
typedef void (*gcode_cmd_t)(const vector<string>&, TimeCalc&, double&);
// Always returns 0 sec
void gcode_dummy(const vector<string>&, TimeCalc&, double&);
// All handled gcode commands
double g1(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double g4(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double g21(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double g28(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double g90(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double g92(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double m82(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double m84(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double m104(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double m106(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double m107(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double m109(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double m117(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double m140(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
double m190(const vector<string>& line_tokens, Point& pos, double& speed, double& e_total_offset);
void g1(const vector<string>& line_tokens, TimeCalc& calc, double& speed);
void g4(const vector<string>& line_tokens, TimeCalc& calc, double& speed);
void g28(const vector<string>& line_tokens, TimeCalc& calc, double& speed);
void g92(const vector<string>& line_tokens, TimeCalc& calc, double& speed);
#endif // GCODE_H_

24596
json.hpp Normal file

File diff suppressed because it is too large Load Diff

188
main.cpp
View File

@ -7,12 +7,14 @@
#include "Point.h"
#include "gcode.h"
#include "json.hpp"
using namespace std;
void usage(char *name)
{
cout << "Usage: " << name << " [file]" << endl;
cout << "Usage:" << endl;
cout << name << " [file] ..." << endl;
}
bool is_gcode(const string& line)
@ -78,44 +80,44 @@ void init_map(map<string, gcode_cmd_t>& gcode_map)
gcode_map["G4"] = g4;
gcode_map["g4"] = g4;
gcode_map["G21"] = g21;
gcode_map["g21"] = g21;
gcode_map["G21"] = gcode_dummy;
gcode_map["g21"] = gcode_dummy;
gcode_map["G28"] = g28;
gcode_map["g28"] = g28;
gcode_map["G90"] = g90;
gcode_map["g90"] = g90;
gcode_map["G90"] = gcode_dummy;
gcode_map["g90"] = gcode_dummy;
gcode_map["G92"] = g92;
gcode_map["g92"] = g92;
gcode_map["M82"] = m82;
gcode_map["m82"] = m82;
gcode_map["M82"] = gcode_dummy;
gcode_map["m82"] = gcode_dummy;
gcode_map["M84"] = m84;
gcode_map["m84"] = m84;
gcode_map["M84"] = gcode_dummy;
gcode_map["m84"] = gcode_dummy;
gcode_map["M104"] = m104;
gcode_map["m104"] = m104;
gcode_map["M104"] = gcode_dummy;
gcode_map["m104"] = gcode_dummy;
gcode_map["M106"] = m106;
gcode_map["m106"] = m106;
gcode_map["M106"] = gcode_dummy;
gcode_map["m106"] = gcode_dummy;
gcode_map["M107"] = m107;
gcode_map["m107"] = m107;
gcode_map["M107"] = gcode_dummy;
gcode_map["m107"] = gcode_dummy;
gcode_map["M109"] = m109;
gcode_map["m109"] = m109;
gcode_map["M109"] = gcode_dummy;
gcode_map["m109"] = gcode_dummy;
gcode_map["M117"] = m117;
gcode_map["m117"] = m117;
gcode_map["M117"] = gcode_dummy;
gcode_map["m117"] = gcode_dummy;
gcode_map["M140"] = m140;
gcode_map["m140"] = m140;
gcode_map["M140"] = gcode_dummy;
gcode_map["m140"] = gcode_dummy;
gcode_map["M190"] = m190;
gcode_map["m190"] = m190;
gcode_map["M190"] = gcode_dummy;
gcode_map["m190"] = gcode_dummy;
}
void print_time(double sec)
@ -131,18 +133,79 @@ void print_time(double sec)
printf("%02d:%02d:%02.0f", hours, min, sec);
}
void init_calc(TimeCalc& calc)
{
ifstream file("config.json");
nlohmann::json conf;
vector<string> conf_keys = {"x", "y", "z"};
try
{
file >> conf;
}
catch (const exception& e)
{
cout << e.what() << endl;
return;
}
file.close();
for (int i = 0; i < conf_keys.size(); ++i)
{
string key = conf_keys[i];
if (conf.contains(key) && conf[key].is_object())
{
if (conf[key].contains("acceleration") && conf[key]["acceleration"].is_number())
{
calc.set_max_acceleration(i, conf[key]["acceleration"]);
}
if (conf[key].contains("velocity") && conf[key]["velocity"].is_number())
{
calc.set_max_velocity(i, conf[key]["velocity"]);
}
if (conf[key].contains("jerk") && conf[key]["jerk"].is_number())
{
calc.set_max_jerk(i, conf[key]["jerk"]);
}
}
}
if (conf.contains("extruders") && conf["extruders"].is_array())
{
for (int i = 0; i < conf["extruders"].size(); ++i)
{
if (conf["extruders"][i].contains("acceleration") && conf["extruders"][i]["acceleration"].is_number())
{
calc.set_max_acceleration(3 + i, conf["extruders"][i]["acceleration"]);
}
if (conf["extruders"][i].contains("velocity") && conf["extruders"][i]["velocity"].is_number())
{
calc.set_max_velocity(3 + i, conf["extruders"][i]["velocity"]);
}
if (conf["extruders"][i].contains("jerk") && conf["extruders"][i]["jerk"].is_number())
{
calc.set_max_jerk(3 + i, conf["extruders"][i]["jerk"]);
}
}
}
}
int main(int argc, char **argv)
{
ifstream file;
string line;
vector<string> filenames(&(argv[1]), &(argv[argc]));
vector<string> line_tokens;
map<string, gcode_cmd_t> gcode_map;
Point pos;
TimeCalc calc;
double speed;
double total_time;
double e_total;
int hours;
int minutes;
@ -152,48 +215,55 @@ int main(int argc, char **argv)
return -1;
}
pos.x = 0;
pos.y = 0;
pos.z = 0;
pos.e = 0;
speed = 0;
total_time = 0;
e_total = 0;
init_map(gcode_map);
file.open(argv[1]);
while (!file.eof())
for (string& fname : filenames)
{
getline(file, line);
if (!is_gcode(remove_comments(line)))
{
continue;
}
line_tokens = tokenize_line(line);
calc.reset();
init_calc(calc);
speed = 0;
if (0 != gcode_map.count(line_tokens[0]))
file.open(fname);
while (!file.eof())
{
total_time += gcode_map[line_tokens[0]](line_tokens, pos, speed, e_total);
getline(file, line);
if (!is_gcode(remove_comments(line)))
{
continue;
}
line_tokens = tokenize_line(line);
if (0 != gcode_map.count(line_tokens[0]))
{
gcode_map[line_tokens[0]](line_tokens, calc, speed);
}
else
{
cout << "Unknown Gcode '" << line_tokens[0] << "'" << endl;
}
}
else
file.close();
if (filenames.size() > 1)
{
cout << "Unknown Gcode '" << line_tokens[0] << "'" << endl;
cout << "--- " << fname << " ---" << endl;
}
calc.flush();
total_time = calc.get_time();
cout << "Filament - " << calc.get_extruder_length(0) << "mm" << endl;
cout << "Estimation - ";
print_time(total_time);
cout << endl;
cout << "Adding 10% - ";
print_time(total_time * 1.1);
cout << endl;
cout << "Removing 10% - ";
print_time(total_time * 0.9);
cout << endl;
}
file.close();
e_total += pos.e;
cout << "Filament - " << e_total << "mm" << endl;
cout << "Estimation - ";
print_time(total_time);
cout << endl;
cout << "Adding 10% - ";
print_time(total_time * 1.1);
cout << endl;
return 0;
}