Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FormerLurker/ArcWelderLib.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFormerLurker <hochgebe@gmail.com>2020-12-13 00:49:33 +0300
committerFormerLurker <hochgebe@gmail.com>2020-12-13 00:49:33 +0300
commit893b8eea5e182457e90db9ddbaac8a7fb435a0c7 (patch)
tree421dd5296fcdf57f807c86a2a78ceb5143201fbe /ArcWelder
parent8cbd08c6c27bb792d28345d24ffc7a7765c35079 (diff)
Prevent arc generation if I and J are both 0 within the current precision. Add default xyz and e precision settings, and enable/disable dynamic gcode precision.
Diffstat (limited to 'ArcWelder')
-rw-r--r--ArcWelder/arc_welder.cpp15
-rw-r--r--ArcWelder/arc_welder.h7
-rw-r--r--ArcWelder/segmented_arc.cpp58
-rw-r--r--ArcWelder/segmented_arc.h4
-rw-r--r--ArcWelder/segmented_shape.cpp50
-rw-r--r--ArcWelder/segmented_shape.h27
6 files changed, 121 insertions, 40 deletions
diff --git a/ArcWelder/arc_welder.cpp b/ArcWelder/arc_welder.cpp
index 9fe02d0..d7b6120 100644
--- a/ArcWelder/arc_welder.cpp
+++ b/ArcWelder/arc_welder.cpp
@@ -46,6 +46,9 @@ arc_welder::arc_welder(
double mm_per_arc_segment,
bool g90_g91_influences_extruder,
bool allow_3d_arcs,
+ bool allow_dynamic_precision,
+ unsigned char default_xyz_precision,
+ unsigned char default_e_precision,
int buffer_size,
progress_callback callback) : current_arc_(
DEFAULT_MIN_SEGMENTS,
@@ -55,7 +58,9 @@ arc_welder::arc_welder(
max_radius,
min_arc_segments,
mm_per_arc_segment,
- allow_3d_arcs
+ allow_3d_arcs,
+ default_xyz_precision,
+ default_e_precision
),
segment_statistics_(
segment_statistic_lengths,
@@ -77,6 +82,7 @@ arc_welder::arc_welder(
target_path_ = target_path;
gcode_position_args_ = get_args_(g90_g91_influences_extruder, buffer_size);
allow_3d_arcs_ = allow_3d_arcs;
+ allow_dynamic_precision_ = allow_dynamic_precision;
notification_period_seconds = 1;
lines_processed_ = 0;
gcodes_processed_ = 0;
@@ -195,7 +201,10 @@ arc_welder_results results;
<< ", min_arc_segments:" << std::setprecision(0) <<current_arc_.get_min_arc_segments()
<< ", mm_per_arc_segment:" << std::setprecision(0) << current_arc_.get_mm_per_arc_segment()
<< ", g90_91_influences_extruder: " << (p_source_position_->get_g90_91_influences_extruder() ? "True" : "False")
- << ", allow_3d_arcs: " << (allow_3d_arcs_ ? "True" : "False");
+ << ", allow_3d_arcs: " << (allow_3d_arcs_ ? "True" : "False")
+ << ", allow_dynamic_precision: " << (allow_dynamic_precision_ ? "True" : "False")
+ << ", default_xyz_precision: " << std::setprecision(0) << (current_arc_.get_xyz_precision())
+ << ", default_e_precision: " << std::setprecision(0) << (current_arc_.get_e_precision());
p_logger_->log(logger_type_, INFO, stream.str());
@@ -407,7 +416,7 @@ int arc_welder::process_gcode(parsed_command cmd, bool is_end, bool is_reprocess
// We need to make sure the printer is using absolute xyz, is extruding, and the extruder axis mode is the same as that of the previous position
// TODO: Handle relative XYZ axis. This is possible, but maybe not so important.
bool is_g1_g2 = cmd.command == "G0" || cmd.command == "G1";
- if (is_g1_g2)
+ if (allow_dynamic_precision_ && is_g1_g2)
{
for (std::vector<parsed_command_parameter>::iterator it = cmd.parameters.begin(); it != cmd.parameters.end(); ++it)
{
diff --git a/ArcWelder/arc_welder.h b/ArcWelder/arc_welder.h
index 0e6bb81..9e6d74a 100644
--- a/ArcWelder/arc_welder.h
+++ b/ArcWelder/arc_welder.h
@@ -412,6 +412,7 @@ struct arc_welder_results {
};
#define DEFAULT_GCODE_BUFFER_SIZE 1000
#define DEFAULT_G90_G91_INFLUENCES_EXTRUDER false
+#define DEFAULT_ALLOW_DYNAMIC_PRECISION false
class arc_welder
{
public:
@@ -425,7 +426,10 @@ public:
int min_arc_segments,
double mm_per_arc_segment,
bool g90_g91_influences_extruder = DEFAULT_G90_G91_INFLUENCES_EXTRUDER,
- bool allow_3d_arcs = DEFAULT_allow_3d_arcs,
+ bool allow_3d_arcs = DEFAULT_ALLOW_3D_ARCS,
+ bool allow_dynamic_precision = DEFAULT_ALLOW_DYNAMIC_PRECISION,
+ unsigned char default_xyz_precision = DEFAULT_XYZ_PRECISION,
+ unsigned char default_e_precision = DEFAULT_E_PRECISION,
int buffer_size = DEFAULT_GCODE_BUFFER_SIZE,
progress_callback callback = NULL);
void set_logger_type(int logger_type);
@@ -451,6 +455,7 @@ private:
std::string target_path_;
double resolution_mm_;
gcode_position_args gcode_position_args_;
+ bool allow_dynamic_precision_;
bool allow_3d_arcs_;
long file_size_;
int lines_processed_;
diff --git a/ArcWelder/segmented_arc.cpp b/ArcWelder/segmented_arc.cpp
index c92809f..0618917 100644
--- a/ArcWelder/segmented_arc.cpp
+++ b/ArcWelder/segmented_arc.cpp
@@ -35,7 +35,8 @@ segmented_arc::segmented_arc() : segmented_shape(DEFAULT_MIN_SEGMENTS, DEFAULT_M
{
max_radius_mm_ = DEFAULT_MAX_RADIUS_MM;
min_arc_segments_ = DEFAULT_MIN_ARC_SEGMENTS,
- allow_3d_arcs_ = DEFAULT_allow_3d_arcs;
+ mm_per_arc_segment_ = DEFAULT_MM_PER_ARC_SEGMENT;
+ allow_3d_arcs_ = DEFAULT_ALLOW_3D_ARCS;
num_firmware_compensations_ = 0;
}
@@ -47,8 +48,10 @@ segmented_arc::segmented_arc(
double max_radius_mm,
int min_arc_segments,
double mm_per_arc_segment,
- bool allow_3d_arcs
-) : segmented_shape(min_segments, max_segments, resolution_mm, path_tolerance_percent)
+ bool allow_3d_arcs,
+ unsigned char default_xyz_precision,
+ unsigned char default_e_precision
+) : segmented_shape(min_segments, max_segments, resolution_mm, path_tolerance_percent, default_xyz_precision, default_e_precision)
{
max_radius_mm_ = max_radius_mm;
if (max_radius_mm > DEFAULT_MAX_RADIUS_MM) {
@@ -210,10 +213,10 @@ bool segmented_arc::try_add_point_internal_(point p, double pd)
double previous_shape_length = original_shape_length_;
original_shape_length_ += pd;
arc original_arc = current_arc_;
- if (arc::try_create_arc(points_, current_arc_, original_shape_length_, max_radius_mm_, resolution_mm_, path_tolerance_percent_, min_arc_segments_, mm_per_arc_segment_, xyz_precision_, allow_3d_arcs_))
+ if (arc::try_create_arc(points_, current_arc_, original_shape_length_, max_radius_mm_, resolution_mm_, path_tolerance_percent_, min_arc_segments_, mm_per_arc_segment_, get_xyz_precision(), allow_3d_arcs_))
{
// See how many arcs will be interpolated
- bool firmware_corrected = false;
+ bool abort_arc = false;
if (min_arc_segments_ > 0 && mm_per_arc_segment_ > 0)
{
double circumference = 2.0 * PI_DOUBLE * current_arc_.radius;
@@ -222,14 +225,24 @@ bool segmented_arc::try_add_point_internal_(point p, double pd)
//num_segments = (int)std::ceil(circumference/approximate_length) * (int)std::ceil(approximate_length / mm_per_arc_segment);
num_segments = (int)std::floor(circumference / original_shape_length_);
if (num_segments < min_arc_segments_) {
- firmware_corrected = true;
- current_arc_ = original_arc;
+ abort_arc = true;
num_firmware_compensations_++;
}
}
}
+ // check for I=0 and J=0
+ if (!abort_arc && utilities::is_zero(current_arc_.get_i(), get_xyz_tolerance()) && utilities::is_zero(current_arc_.get_j(), get_xyz_tolerance()))
+ {
+ abort_arc = true;
+ }
- if (!firmware_corrected)
+ if (abort_arc)
+ {
+ // This arc has been cancelled either due to firmware correction,
+ // or because both I and J == 0
+ current_arc_ = original_arc;
+ }
+ else if (!abort_arc)
{
if (!is_shape())
{
@@ -262,8 +275,8 @@ std::string segmented_arc::get_shape_gcode_(bool has_e, double e, double f) cons
std::string gcode;
- double i = current_arc_.center.x - current_arc_.start_point.x;
- double j = current_arc_.center.y - current_arc_.start_point.y;
+ double i = current_arc_.get_i();
+ double j = current_arc_.get_j();
// Here is where the performance part kicks in (these are expensive calls) that makes things a bit ugly.
// there are a few cases we need to take into consideration before choosing our sprintf string
// create the XYZ portion
@@ -279,35 +292,40 @@ std::string segmented_arc::get_shape_gcode_(bool has_e, double e, double f) cons
}
// Add X, Y, I and J
gcode += " X";
- gcode += utilities::to_string(current_arc_.end_point.x, xyz_precision_, buf, false);
+ gcode += utilities::to_string(current_arc_.end_point.x, get_xyz_precision(), buf, false);
gcode += " Y";
- gcode += utilities::to_string(current_arc_.end_point.y, xyz_precision_, buf, false);
+ gcode += utilities::to_string(current_arc_.end_point.y, get_xyz_precision(), buf, false);
if (allow_3d_arcs_)
{
// We may need to add a z coordinate
double z_initial = current_arc_.start_point.z;
double z_final = current_arc_.end_point.z;
- if (!utilities::is_equal(z_initial, z_final, std::pow(10.0, -1.0 * xyz_precision_)))
+ if (!utilities::is_equal(z_initial, z_final, get_xyz_tolerance()))
{
// The z axis has changed within the precision of the gcode coordinates
gcode += " Z";
- gcode += utilities::to_string(current_arc_.end_point.z, xyz_precision_, buf, false);
+ gcode += utilities::to_string(current_arc_.end_point.z, get_xyz_precision(), buf, false);
}
}
- gcode += " I";
- gcode += utilities::to_string(i, xyz_precision_, buf, false);
-
- gcode += " J";
- gcode += utilities::to_string(j, xyz_precision_, buf, false);
+ if (!utilities::is_zero(i, get_xyz_tolerance()))
+ {
+ gcode += " I";
+ gcode += utilities::to_string(i, get_xyz_precision(), buf, false);
+ }
+ if (!utilities::is_zero(j, get_xyz_tolerance()))
+ {
+ gcode += " J";
+ gcode += utilities::to_string(j, get_xyz_precision(), buf, false);
+ }
// Add E if it appears
if (has_e)
{
gcode += " E";
- gcode += utilities::to_string(e, e_precision_, buf, false);
+ gcode += utilities::to_string(e, get_e_precision(), buf, false);
}
// Add F if it appears
diff --git a/ArcWelder/segmented_arc.h b/ArcWelder/segmented_arc.h
index a51cbbd..36d20da 100644
--- a/ArcWelder/segmented_arc.h
+++ b/ArcWelder/segmented_arc.h
@@ -43,7 +43,9 @@ public:
double max_radius_mm = DEFAULT_MAX_RADIUS_MM,
int min_arc_segments = DEFAULT_MIN_ARC_SEGMENTS,
double mm_per_arc_segment = DEFAULT_MM_PER_ARC_SEGMENT,
- bool allow_3d_arcs = DEFAULT_allow_3d_arcs
+ bool allow_3d_arcs = DEFAULT_ALLOW_3D_ARCS,
+ unsigned char default_xyz_precision = DEFAULT_XYZ_PRECISION,
+ unsigned char default_e_precision = DEFAULT_E_PRECISION
);
virtual ~segmented_arc();
virtual bool try_add_point(point p, double e_relative);
diff --git a/ArcWelder/segmented_shape.cpp b/ArcWelder/segmented_shape.cpp
index 65995b4..f505d59 100644
--- a/ArcWelder/segmented_shape.cpp
+++ b/ArcWelder/segmented_shape.cpp
@@ -323,6 +323,16 @@ bool circle::is_over_deviation(const array_list<point>& points, const double res
#pragma region Arc Functions
+double arc::get_i() const
+{
+ return center.x - start_point.x;
+}
+
+double arc::get_j() const
+{
+ return center.y - start_point.y;
+}
+
bool arc::try_create_arc(
const circle& c,
const point& start_point,
@@ -477,11 +487,11 @@ bool arc::try_create_arc(
#pragma endregion
-segmented_shape::segmented_shape(int min_segments, int max_segments, double resolution_mm, double path_tolerance_percnet) : points_(max_segments)
+segmented_shape::segmented_shape(int min_segments, int max_segments, double resolution_mm, double path_tolerance_percnet, unsigned char default_xyz_precision, unsigned char default_e_precision) : points_(max_segments)
{
- xyz_precision_ = DEFAULT_XYZ_PRECISION;
- e_precision_ = DEFAULT_E_PRECISION;
+ set_xyz_precision(default_xyz_precision);
+ e_precision_ = default_e_precision;
max_segments_ = max_segments;
path_tolerance_percent_ = path_tolerance_percnet;
resolution_mm_ = resolution_mm / 2.0; // divide by 2 because it is + or - 1/2 of the desired resolution.
@@ -500,21 +510,47 @@ segmented_shape::~segmented_shape()
}
+unsigned char segmented_shape::get_xyz_precision() const
+{
+ return xyz_precision_;
+}
+
+double segmented_shape::get_xyz_tolerance() const
+{
+ return xyz_tolerance_;
+}
+
+unsigned char segmented_shape::get_e_precision() const
+{
+ return e_precision_;
+}
+
+void segmented_shape::set_xyz_precision(unsigned char precision)
+{
+ xyz_precision_ = precision;
+ set_xyz_tolerance_from_precision();
+}
+
+void segmented_shape::set_xyz_tolerance_from_precision()
+{
+ xyz_tolerance_ = std::pow(10.0, -1.0 * static_cast<double>(xyz_precision_));
+}
+
void segmented_shape::reset_precision()
{
- xyz_precision_ = DEFAULT_XYZ_PRECISION;
+ set_xyz_precision(DEFAULT_XYZ_PRECISION);
e_precision_ = DEFAULT_E_PRECISION;
}
-void segmented_shape::update_xyz_precision(int precision)
+void segmented_shape::update_xyz_precision(unsigned char precision)
{
if (xyz_precision_ < precision)
{
- xyz_precision_ = precision;
+ set_xyz_precision(precision);
}
}
-void segmented_shape::update_e_precision(int precision)
+void segmented_shape::update_e_precision(unsigned char precision)
{
if (e_precision_ < precision)
{
diff --git a/ArcWelder/segmented_shape.h b/ArcWelder/segmented_shape.h
index eda6a7c..3b8e807 100644
--- a/ArcWelder/segmented_shape.h
+++ b/ArcWelder/segmented_shape.h
@@ -121,7 +121,7 @@ struct circle {
};
#define DEFAULT_RESOLUTION_MM 0.05
-#define DEFAULT_allow_3d_arcs false
+#define DEFAULT_ALLOW_3D_ARCS false
#define DEFAULT_MIN_ARC_SEGMENTS 0
#define DEFAULT_MM_PER_ARC_SEGMENT 0
struct arc : circle
@@ -153,6 +153,9 @@ struct arc : circle
double max_deviation;
point start_point;
point end_point;
+
+ double get_i() const;
+ double get_j() const;
// Statis functions
static bool try_create_arc(
const circle& c,
@@ -163,7 +166,7 @@ struct arc : circle
double approximate_length,
double resolution = DEFAULT_RESOLUTION_MM,
double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT,
- bool allow_3d_arcs = DEFAULT_allow_3d_arcs);
+ bool allow_3d_arcs = DEFAULT_ALLOW_3D_ARCS);
static bool try_create_arc(
const array_list<point>& points,
@@ -175,7 +178,7 @@ struct arc : circle
int min_arc_segments = DEFAULT_MIN_ARC_SEGMENTS,
double mm_per_arc_segment = DEFAULT_MM_PER_ARC_SEGMENT,
int xyz_precision = DEFAULT_XYZ_PRECISION,
- bool allow_3d_arcs = DEFAULT_allow_3d_arcs);
+ bool allow_3d_arcs = DEFAULT_ALLOW_3D_ARCS);
};
double distance_from_segment(segment s, point p);
@@ -189,7 +192,9 @@ public:
segmented_shape(int min_segments = DEFAULT_MIN_SEGMENTS,
int max_segments = DEFAULT_MAX_SEGMENTS,
double resolution_mm = DEFAULT_RESOLUTION_MM,
- double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT
+ double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT,
+ unsigned char default_xyz_precision = DEFAULT_XYZ_PRECISION,
+ unsigned char default_e_precision = DEFAULT_E_PRECISION
);
segmented_shape& operator=(const segmented_shape& pos);
virtual ~segmented_shape();
@@ -202,8 +207,8 @@ public:
double get_shape_e_relative();
void set_resolution_mm(double resolution_mm);
void reset_precision();
- void update_xyz_precision(int precision);
- void update_e_precision(int precision);
+ void update_xyz_precision(unsigned char precision);
+ void update_e_precision(unsigned char precision);
virtual bool is_shape() const;
// public virtual functions
virtual void clear();
@@ -213,11 +218,12 @@ public:
virtual std::string get_shape_gcode_absolute(double e_abs_start);
virtual std::string get_shape_gcode_relative();
bool is_extruding();
+ unsigned char get_xyz_precision() const;
+ unsigned char get_e_precision() const;
+ double get_xyz_tolerance() const;
protected:
array_list<point> points_;
void set_is_shape(bool value);
- unsigned char xyz_precision_;
- unsigned char e_precision_;
double original_shape_length_;
double e_relative_;
bool is_extruding_;
@@ -227,5 +233,10 @@ protected:
private:
int min_segments_;
int max_segments_;
+ unsigned char xyz_precision_;
+ double xyz_tolerance_;
+ unsigned char e_precision_;
+ void set_xyz_tolerance_from_precision();
+ void set_xyz_precision(unsigned char precision);
};