mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-05-11 21:19:07 +08:00
Merge remote-tracking branch 'origin/time_estimate'
This commit is contained in:
commit
eaac587467
@ -15,6 +15,7 @@ static const float DEFAULT_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 500.0f,
|
||||
static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // from Prusa Firmware (Configuration.h)
|
||||
static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h)
|
||||
static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h)
|
||||
static const float DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent
|
||||
|
||||
static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f;
|
||||
|
||||
@ -142,28 +143,36 @@ namespace Slic3r {
|
||||
|
||||
void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode)
|
||||
{
|
||||
reset();
|
||||
|
||||
_parser.parse_buffer(gcode,
|
||||
[this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
|
||||
{ this->_process_gcode_line(reader, line); });
|
||||
_calculate_time();
|
||||
reset();
|
||||
|
||||
_reset();
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::calculate_time_from_file(const std::string& file)
|
||||
{
|
||||
reset();
|
||||
|
||||
_parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2));
|
||||
_calculate_time();
|
||||
reset();
|
||||
|
||||
_reset();
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::calculate_time_from_lines(const std::vector<std::string>& gcode_lines)
|
||||
{
|
||||
reset();
|
||||
|
||||
auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
|
||||
{ this->_process_gcode_line(reader, line); };
|
||||
for (const std::string& line : gcode_lines)
|
||||
_parser.parse_line(line, action);
|
||||
_calculate_time();
|
||||
reset();
|
||||
|
||||
_reset();
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line)
|
||||
@ -283,6 +292,16 @@ namespace Slic3r {
|
||||
return _state.minimum_travel_feedrate;
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::set_extrude_factor_override_percentage(float percentage)
|
||||
{
|
||||
_state.extrude_factor_override_percentage = percentage;
|
||||
}
|
||||
|
||||
float GCodeTimeEstimator::get_extrude_factor_override_percentage() const
|
||||
{
|
||||
return _state.extrude_factor_override_percentage;
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::set_dialect(GCodeTimeEstimator::EDialect dialect)
|
||||
{
|
||||
_state.dialect = dialect;
|
||||
@ -350,6 +369,7 @@ namespace Slic3r {
|
||||
set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION);
|
||||
set_minimum_feedrate(DEFAULT_MINIMUM_FEEDRATE);
|
||||
set_minimum_travel_feedrate(DEFAULT_MINIMUM_TRAVEL_FEEDRATE);
|
||||
set_extrude_factor_override_percentage(DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE);
|
||||
|
||||
for (unsigned char a = X; a < Num_Axis; ++a)
|
||||
{
|
||||
@ -362,7 +382,7 @@ namespace Slic3r {
|
||||
|
||||
void GCodeTimeEstimator::reset()
|
||||
{
|
||||
_blocks.clear();
|
||||
_time = 0.0f;
|
||||
_reset();
|
||||
}
|
||||
|
||||
@ -392,6 +412,8 @@ namespace Slic3r {
|
||||
|
||||
void GCodeTimeEstimator::_reset()
|
||||
{
|
||||
_blocks.clear();
|
||||
|
||||
_curr.reset();
|
||||
_prev.reset();
|
||||
|
||||
@ -408,7 +430,7 @@ namespace Slic3r {
|
||||
_reverse_pass();
|
||||
_recalculate_trapezoids();
|
||||
|
||||
_time = get_additional_time();
|
||||
_time += get_additional_time();
|
||||
|
||||
for (const Block& block : _blocks)
|
||||
{
|
||||
@ -478,6 +500,11 @@ namespace Slic3r {
|
||||
{
|
||||
switch (::atoi(&cmd[1]))
|
||||
{
|
||||
case 1: // Sleep or Conditional stop
|
||||
{
|
||||
_processM1(line);
|
||||
break;
|
||||
}
|
||||
case 82: // Set extruder to absolute mode
|
||||
{
|
||||
_processM82(line);
|
||||
@ -513,6 +540,11 @@ namespace Slic3r {
|
||||
_processM205(line);
|
||||
break;
|
||||
}
|
||||
case 221: // Set extrude factor override percentage
|
||||
{
|
||||
_processM221(line);
|
||||
break;
|
||||
}
|
||||
case 566: // Set allowable instantaneous speed change
|
||||
{
|
||||
_processM566(line);
|
||||
@ -578,6 +610,9 @@ namespace Slic3r {
|
||||
for (unsigned char a = X; a < Num_Axis; ++a)
|
||||
{
|
||||
_curr.axis_feedrate[a] = _curr.feedrate * block.delta_pos[a] * invDistance;
|
||||
if (a == E)
|
||||
_curr.axis_feedrate[a] *= get_extrude_factor_override_percentage();
|
||||
|
||||
_curr.abs_axis_feedrate[a] = std::abs(_curr.axis_feedrate[a]);
|
||||
if (_curr.abs_axis_feedrate[a] > 0.0f)
|
||||
min_feedrate_factor = std::min(min_feedrate_factor, get_axis_max_feedrate((EAxis)a) / _curr.abs_axis_feedrate[a]);
|
||||
@ -718,6 +753,8 @@ namespace Slic3r {
|
||||
if (line.has_value('S', value))
|
||||
add_additional_time(value);
|
||||
}
|
||||
|
||||
_simulate_st_synchronize();
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processG20(const GCodeReader::GCodeLine& line)
|
||||
@ -747,16 +784,6 @@ namespace Slic3r {
|
||||
set_positioning_xyz_type(Relative);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processM82(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
set_positioning_e_type(Absolute);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processM83(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
set_positioning_e_type(Relative);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processG92(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
float lengthsScaleFactor = (get_units() == Inches) ? INCHES_TO_MM : 1.0f;
|
||||
@ -785,6 +812,8 @@ namespace Slic3r {
|
||||
set_axis_position(E, line.e() * lengthsScaleFactor);
|
||||
anyFound = true;
|
||||
}
|
||||
else
|
||||
_simulate_st_synchronize();
|
||||
|
||||
if (!anyFound)
|
||||
{
|
||||
@ -795,6 +824,21 @@ namespace Slic3r {
|
||||
}
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processM1(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
_simulate_st_synchronize();
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processM82(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
set_positioning_e_type(Absolute);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processM83(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
set_positioning_e_type(Relative);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processM109(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
// TODO
|
||||
@ -880,6 +924,14 @@ namespace Slic3r {
|
||||
set_minimum_travel_feedrate(value);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processM221(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
float value_s;
|
||||
float value_t;
|
||||
if (line.has_value('S', value_s) && !line.has_value('T', value_t))
|
||||
set_extrude_factor_override_percentage(value_s * 0.01f);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_processM566(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
if (line.has_x())
|
||||
@ -895,77 +947,71 @@ namespace Slic3r {
|
||||
set_axis_max_jerk(E, line.e() * MMMIN_TO_MMSEC);
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_forward_pass()
|
||||
void GCodeTimeEstimator::_simulate_st_synchronize()
|
||||
{
|
||||
Block* block[2] = { nullptr, nullptr };
|
||||
|
||||
for (Block& b : _blocks)
|
||||
{
|
||||
block[0] = block[1];
|
||||
block[1] = &b;
|
||||
_planner_forward_pass_kernel(block[0], block[1]);
|
||||
_calculate_time();
|
||||
_reset();
|
||||
}
|
||||
|
||||
_planner_forward_pass_kernel(block[1], nullptr);
|
||||
void GCodeTimeEstimator::_forward_pass()
|
||||
{
|
||||
if (_blocks.size() > 1)
|
||||
{
|
||||
for (unsigned int i = 0; i < (unsigned int)_blocks.size() - 1; ++i)
|
||||
{
|
||||
_planner_forward_pass_kernel(_blocks[i], _blocks[i + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_reverse_pass()
|
||||
{
|
||||
Block* block[2] = { nullptr, nullptr };
|
||||
|
||||
for (int i = (int)_blocks.size() - 1; i >= 0; --i)
|
||||
if (_blocks.size() > 1)
|
||||
{
|
||||
block[1] = block[0];
|
||||
block[0] = &_blocks[i];
|
||||
_planner_reverse_pass_kernel(block[0], block[1]);
|
||||
for (int i = (int)_blocks.size() - 1; i >= 1; --i)
|
||||
{
|
||||
_planner_reverse_pass_kernel(_blocks[i - 1], _blocks[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_planner_forward_pass_kernel(Block* prev, Block* curr)
|
||||
void GCodeTimeEstimator::_planner_forward_pass_kernel(Block& prev, Block& curr)
|
||||
{
|
||||
if (prev == nullptr || curr == nullptr)
|
||||
//FIXME something is fishy here. Review and compare with the firmware.
|
||||
// if (prev == nullptr)
|
||||
return;
|
||||
|
||||
// If the previous block is an acceleration block, but it is not long enough to complete the
|
||||
// full speed change within the block, we need to adjust the entry speed accordingly. Entry
|
||||
// speeds have already been reset, maximized, and reverse planned by reverse planner.
|
||||
// If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck.
|
||||
if (!prev->flags.nominal_length)
|
||||
if (!prev.flags.nominal_length)
|
||||
{
|
||||
if (prev->feedrate.entry < curr->feedrate.entry)
|
||||
if (prev.feedrate.entry < curr.feedrate.entry)
|
||||
{
|
||||
float entry_speed = std::min(curr->feedrate.entry, Block::max_allowable_speed(-prev->acceleration, prev->feedrate.entry, prev->move_length()));
|
||||
float entry_speed = std::min(curr.feedrate.entry, Block::max_allowable_speed(-prev.acceleration, prev.feedrate.entry, prev.move_length()));
|
||||
|
||||
// Check for junction speed change
|
||||
if (curr->feedrate.entry != entry_speed)
|
||||
if (curr.feedrate.entry != entry_speed)
|
||||
{
|
||||
curr->feedrate.entry = entry_speed;
|
||||
curr->flags.recalculate = true;
|
||||
curr.feedrate.entry = entry_speed;
|
||||
curr.flags.recalculate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::_planner_reverse_pass_kernel(Block* curr, Block* next)
|
||||
void GCodeTimeEstimator::_planner_reverse_pass_kernel(Block& curr, Block& next)
|
||||
{
|
||||
if ((curr == nullptr) || (next == nullptr))
|
||||
return;
|
||||
|
||||
// If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising.
|
||||
// If not, block in state of acceleration or deceleration. Reset entry speed to maximum and
|
||||
// check for maximum allowable speed reductions to ensure maximum possible planned speed.
|
||||
if (curr->feedrate.entry != curr->max_entry_speed)
|
||||
if (curr.feedrate.entry != curr.max_entry_speed)
|
||||
{
|
||||
// If nominal length true, max junction speed is guaranteed to be reached. Only compute
|
||||
// for max allowable speed if block is decelerating and nominal length is false.
|
||||
if (!curr->flags.nominal_length && (curr->max_entry_speed > next->feedrate.entry))
|
||||
curr->feedrate.entry = std::min(curr->max_entry_speed, Block::max_allowable_speed(-curr->acceleration, next->feedrate.entry, curr->move_length()));
|
||||
if (!curr.flags.nominal_length && (curr.max_entry_speed > next.feedrate.entry))
|
||||
curr.feedrate.entry = std::min(curr.max_entry_speed, Block::max_allowable_speed(-curr.acceleration, next.feedrate.entry, curr.move_length()));
|
||||
else
|
||||
curr->feedrate.entry = curr->max_entry_speed;
|
||||
curr.feedrate.entry = curr.max_entry_speed;
|
||||
|
||||
curr->flags.recalculate = true;
|
||||
curr.flags.recalculate = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,7 @@ namespace Slic3r {
|
||||
float additional_time; // s
|
||||
float minimum_feedrate; // mm/s
|
||||
float minimum_travel_feedrate; // mm/s
|
||||
float extrude_factor_override_percentage;
|
||||
};
|
||||
|
||||
public:
|
||||
@ -218,6 +219,9 @@ namespace Slic3r {
|
||||
void set_minimum_travel_feedrate(float feedrate_mm_sec);
|
||||
float get_minimum_travel_feedrate() const;
|
||||
|
||||
void set_extrude_factor_override_percentage(float percentage);
|
||||
float get_extrude_factor_override_percentage() const;
|
||||
|
||||
void set_dialect(EDialect dialect);
|
||||
EDialect get_dialect() const;
|
||||
|
||||
@ -278,6 +282,9 @@ namespace Slic3r {
|
||||
// Set Position
|
||||
void _processG92(const GCodeReader::GCodeLine& line);
|
||||
|
||||
// Sleep or Conditional stop
|
||||
void _processM1(const GCodeReader::GCodeLine& line);
|
||||
|
||||
// Set extruder to absolute mode
|
||||
void _processM82(const GCodeReader::GCodeLine& line);
|
||||
|
||||
@ -299,14 +306,20 @@ namespace Slic3r {
|
||||
// Advanced settings
|
||||
void _processM205(const GCodeReader::GCodeLine& line);
|
||||
|
||||
// Set extrude factor override percentage
|
||||
void _processM221(const GCodeReader::GCodeLine& line);
|
||||
|
||||
// Set allowable instantaneous speed change
|
||||
void _processM566(const GCodeReader::GCodeLine& line);
|
||||
|
||||
// Simulates firmware st_synchronize() call
|
||||
void _simulate_st_synchronize();
|
||||
|
||||
void _forward_pass();
|
||||
void _reverse_pass();
|
||||
|
||||
void _planner_forward_pass_kernel(Block* prev, Block* curr);
|
||||
void _planner_reverse_pass_kernel(Block* curr, Block* next);
|
||||
void _planner_forward_pass_kernel(Block& prev, Block& curr);
|
||||
void _planner_reverse_pass_kernel(Block& curr, Block& next);
|
||||
|
||||
void _recalculate_trapezoids();
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user