Fixed toolpaths generation for gcode line G2 and G3
This commit is contained in:
parent
7fbaa3e8fd
commit
828dd5ddf8
@ -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
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user