Fixed toolpaths generation for gcode line G2 and G3

This commit is contained in:
enricoturri1966 2022-07-27 15:16:20 +02:00
parent 7fbaa3e8fd
commit 828dd5ddf8
2 changed files with 26 additions and 26 deletions

View File

@ -2931,7 +2931,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
#if ENABLE_PROCESS_G2_G3_LINES #if ENABLE_PROCESS_G2_G3_LINES
void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise) void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise)
{ {
if (!line.has('X') || !line.has('Y') || !line.has('I') || !line.has('J')) if (!line.has('I') || !line.has('J'))
return; return;
// relative center // relative center
@ -2962,7 +2962,7 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc
Vec3d relative_start() const { return start - center; } Vec3d relative_start() const { return start - center; }
Vec3d relative_end() const { return end - center; } Vec3d relative_end() const { return end - center; }
bool closed() const { return end.isApprox(start); } bool is_full_circle() const { return std::abs(delta_x()) < EPSILON && std::abs(delta_y()) < EPSILON; }
}; };
Arc arc; Arc arc;
@ -3005,7 +3005,7 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc
const Vec3d rel_arc_end = arc.relative_end(); const Vec3d rel_arc_end = arc.relative_end();
// arc angle // arc angle
if (arc.closed()) if (arc.is_full_circle())
arc.angle = 2.0 * PI; arc.angle = 2.0 * PI;
else { else {
arc.angle = std::atan2(rel_arc_start.x() * rel_arc_end.y() - rel_arc_start.y() * rel_arc_end.x(), arc.angle = std::atan2(rel_arc_start.x() * rel_arc_end.y() - rel_arc_start.y() * rel_arc_end.x(),
@ -3057,24 +3057,23 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc
// calculate arc segments // calculate arc segments
// reference: // reference:
// Prusa-Firmware\Firmware\motion_control.cpp - mc_arc() // Prusa-Firmware\Firmware\motion_control.cpp - mc_arc()
// https://github.com/prusa3d/Prusa-Firmware/blob/MK3/Firmware/motion_control.cpp
// segments count // segments count
static const double MM_PER_ARC_SEGMENT = 1.0; static const double MM_PER_ARC_SEGMENT = 0.5;
const size_t segments = std::max<size_t>(std::floor(travel_length / MM_PER_ARC_SEGMENT), 1); const size_t segments = std::ceil(travel_length / MM_PER_ARC_SEGMENT);
assert(segments >= 1);
const double theta_per_segment = arc.angle / double(segments); const double theta_per_segment = arc.angle / double(segments);
const double z_per_segment = arc.delta_z() / double(segments); const double z_per_segment = arc.delta_z() / double(segments);
const double extruder_per_segment = (extrusion.has_value()) ? *extrusion / double(segments) : 0.0; const double extruder_per_segment = (extrusion.has_value()) ? *extrusion / double(segments) : 0.0;
double cos_T = 1.0 - 0.5 * sqr(theta_per_segment); // Small angle approximation const double sq_theta_per_segment = sqr(theta_per_segment);
double sin_T = theta_per_segment; const double cos_T = 1.0 - 0.5 * sq_theta_per_segment; // Small angle approximation
const double sin_T = theta_per_segment - sq_theta_per_segment * theta_per_segment / 6.0; // Small angle approximation
AxisCoords prev_target = m_start_position; AxisCoords prev_target = m_start_position;
AxisCoords arc_target; AxisCoords arc_target;
double sin_Ti;
double cos_Ti;
double r_axisi;
size_t count = 0;
// Initialize the linear axis // Initialize the linear axis
arc_target[Z] = m_start_position[Z]; arc_target[Z] = m_start_position[Z];
@ -3088,22 +3087,23 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc
std::string gcode; std::string gcode;
for (size_t i = 1; i < segments; ++i) { // Increment (segments-1) size_t n_arc_correction = N_ARC_CORRECTION;
if (count < N_ARC_CORRECTION) {
// Apply vector rotation matrix for (size_t i = 1; i < segments; ++i) {
r_axisi = curr_rel_arc_start.x() * sin_T + curr_rel_arc_start.y() * cos_T; if (n_arc_correction-- == 0) {
curr_rel_arc_start.x() = curr_rel_arc_start.x() * cos_T - curr_rel_arc_start.y() * sin_T; // Calculate the actual position for r_axis_x and r_axis_y
curr_rel_arc_start.y() = r_axisi; const double cos_Ti = ::cos((double)i * theta_per_segment);
count++; const double sin_Ti = ::sin((double)i * theta_per_segment);
}
else {
// Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments.
// Compute exact location by applying transformation matrix from initial radius vector(=-offset).
cos_Ti = ::cos(double(i) * theta_per_segment);
sin_Ti = ::sin(double(i) * theta_per_segment);
curr_rel_arc_start.x() = -double(rel_center.x()) * cos_Ti + double(rel_center.y()) * sin_Ti; curr_rel_arc_start.x() = -double(rel_center.x()) * cos_Ti + double(rel_center.y()) * sin_Ti;
curr_rel_arc_start.y() = -double(rel_center.x()) * sin_Ti - double(rel_center.y()) * cos_Ti; curr_rel_arc_start.y() = -double(rel_center.x()) * sin_Ti - double(rel_center.y()) * cos_Ti;
count = 0; // reset n_arc_correction
n_arc_correction = N_ARC_CORRECTION;
}
else {
// Calculate X and Y using the small angle approximation
const float r_axisi = curr_rel_arc_start.x() * sin_T + curr_rel_arc_start.y() * cos_T;
curr_rel_arc_start.x() = curr_rel_arc_start.x() * cos_T - curr_rel_arc_start.y() * sin_T;
curr_rel_arc_start.y() = r_axisi;
} }
// Update arc_target location // Update arc_target location

View File

@ -2322,7 +2322,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
if (move.type == EMoveType::Extrude) { if (move.type == EMoveType::Extrude) {
#if ENABLE_PROCESS_G2_G3_LINES #if ENABLE_PROCESS_G2_G3_LINES
if (move.extrusion_role != erNone && !move.internal_only) { if (!move.internal_only) {
#endif // ENABLE_PROCESS_G2_G3_LINES #endif // ENABLE_PROCESS_G2_G3_LINES
// layers zs // layers zs
const double* const last_z = m_layers.empty() ? nullptr : &m_layers.get_zs().back(); const double* const last_z = m_layers.empty() ? nullptr : &m_layers.get_zs().back();