diff options
Diffstat (limited to 'ArcWelderInverseProcessor/arc_interpolation.cpp')
-rw-r--r-- | ArcWelderInverseProcessor/arc_interpolation.cpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/ArcWelderInverseProcessor/arc_interpolation.cpp b/ArcWelderInverseProcessor/arc_interpolation.cpp new file mode 100644 index 0000000..9ef4e9e --- /dev/null +++ b/ArcWelderInverseProcessor/arc_interpolation.cpp @@ -0,0 +1,246 @@ +#include "arc_interpolation.h" +#include <string> +#include "gcode_position.h" +#include "marlin_1.h" +#include "marlin_2.h" +#include "repetier.h" +#include "prusa.h" +#include "smoothieware.h" +#include "utilities.h" + + +gcode_position_args arc_interpolation::get_args_(bool g90_g91_influences_extruder, int buffer_size) +{ + gcode_position_args args; + // Configure gcode_position_args + args.g90_influences_extruder = g90_g91_influences_extruder; + args.position_buffer_size = buffer_size; + args.autodetect_position = true; + args.home_x = 0; + args.home_x_none = true; + args.home_y = 0; + args.home_y_none = true; + args.home_z = 0; + args.home_z_none = true; + args.shared_extruder = true; + args.zero_based_extruder = true; + + + args.default_extruder = 0; + args.xyz_axis_default_mode = "absolute"; + args.e_axis_default_mode = "absolute"; + args.units_default = "millimeters"; + args.location_detection_commands = std::vector<std::string>(); + args.is_bound_ = false; + args.is_circular_bed = false; + args.x_min = -9999; + args.x_max = 9999; + args.y_min = -9999; + args.y_max = 9999; + args.z_min = -9999; + args.z_max = 9999; + return args; +} + +arc_interpolation::arc_interpolation() +{ + p_current_firmware_ = NULL; +} + +arc_interpolation::arc_interpolation(arc_interpolation_args args) +{ + args_ = args; + switch (args.firmware_args.firmware_type) + { + case firmware_types::MARLIN_1: + p_current_firmware_ = new marlin_1(args.firmware_args); + break; + case firmware_types::MARLIN_2: + p_current_firmware_ = new marlin_2(args.firmware_args); + break; + case firmware_types::REPETIER: + p_current_firmware_ = new repetier(args.firmware_args); + break; + case firmware_types::PRUSA: + p_current_firmware_ = new prusa(args.firmware_args); + break; + case firmware_types::SMOOTHIEWARE: + p_current_firmware_ = new smoothieware(args.firmware_args); + } + // Initialize the source position + p_source_position_ = new gcode_position(get_args_(p_current_firmware_->get_g90_g91_influences_extruder(), DEFAULT_GCODE_BUFFER_SIZE)); +} + +arc_interpolation::~arc_interpolation() +{ + delete p_source_position_; + if (p_current_firmware_ != NULL) + { + delete p_current_firmware_; + } + +} + +void arc_interpolation::process() +{ + // Create a stringstream we can use for messaging. + std::stringstream stream; + + // Create a current and target position variable for arc processing + firmware_state state; + firmware_position current; + firmware_position target; + // I, J, and R parameter values + double i=0, j=0, r=0; + // bool values for is_clockwise and is_relative + bool is_clockwise = false, is_relative = false; + // e absolute offset, in case we are outputting absolute e + double offset_absolute_e = 0; + + int read_lines_before_clock_check = 5000; + //std::cout << "stabilization::process_file - Processing file.\r\n"; + stream << "Decompressing gcode file."; + stream << "Source File: " << args_.source_path << "\n"; + stream << "Target File: " << args_.target_path << "\n"; + std::cout << stream.str(); + const clock_t start_clock = clock(); + + // Create the source file read stream and target write stream + std::ifstream gcode_file; + gcode_file.open(args_.source_path.c_str()); + output_file_.open(args_.target_path.c_str()); + std::string line; + int lines_with_no_commands = 0; + gcode_file.sync_with_stdio(false); + output_file_.sync_with_stdio(false); + gcode_parser parser; + int gcodes_processed = 0; + if (gcode_file.is_open()) + { + if (output_file_.is_open()) + { + parsed_command cmd; + // Communicate every second + while (std::getline(gcode_file, line)) + { + lines_processed_++; + + cmd.clear(); + parser.try_parse_gcode(line.c_str(), cmd); + bool has_gcode = false; + if (cmd.gcode.length() > 0) + { + has_gcode = true; + gcodes_processed++; + } + else + { + lines_with_no_commands++; + } + + p_source_position_->update(cmd, lines_processed_, gcodes_processed, -1); + + if (cmd.command == "G2" || cmd.command == "G3") + { + // increment the number of arc commands encountered + num_arc_commands_++; + // Get the current and previous positions + position* p_cur_pos = p_source_position_->get_current_position_ptr(); + position* p_pre_pos = p_source_position_->get_previous_position_ptr(); + // create the current and target positions + current.x = p_pre_pos->get_gcode_x(); + current.y = p_pre_pos->get_gcode_y(); + current.z = p_pre_pos->get_gcode_z(); + current.e = p_pre_pos->get_current_extruder().get_offset_e(); + current.f = p_pre_pos->f; + // set the current firmware position + p_current_firmware_->set_current_position(current); + + target.x = p_cur_pos->get_gcode_x(); + target.y = p_cur_pos->get_gcode_y(); + target.z = p_cur_pos->get_gcode_z(); + target.e = p_cur_pos->get_current_extruder().get_offset_e(); + target.f = p_cur_pos->f; + + state.is_extruder_relative = p_pre_pos->is_extruder_relative; + state.is_relative = p_pre_pos->is_relative; + // set the current firmware state + p_current_firmware_->set_current_state(state); + + // get I, J, and R + i = 0; + j = 0; + r = 0; + for (unsigned int index = 0; index < cmd.parameters.size(); index++) + { + parsed_command_parameter p = cmd.parameters[index]; + if (p.name == "I") + { + i = p.double_value; + } + else if (p.name == "J") + { + j = p.double_value; + } + else if (p.name == "R") + { + r = p.double_value; + } + } + + // If r is 0, calculate the radius + if(r==0) + { + r = utilities::hypot(i, j); + } + + is_clockwise = cmd.command == "G2" ? 1 : 0; + is_relative = p_cur_pos->is_extruder_relative; + offset_absolute_e = p_pre_pos->get_current_extruder().get_offset_e(); + + // run the callback and capture any created gcode commands + std::string gcodes = p_current_firmware_->interpolate_arc(target, i, j, r, is_clockwise); + if (gcodes.length() > 0) + { + // there are gcodes to write, write them! + output_file_ << gcodes << "\n"; + } + } + else + { + // Nothing to do with the current line, just write it to disk. + output_file_ << line << "\n"; + } + + } + output_file_.close(); + } + else + { + std::cout << "Unable to open the output file for writing.\n"; + } + std::cout << "Closing the input file.\n"; + gcode_file.close(); + } + else + { + std::cout << "Unable to open the gcode file for processing.\n"; + } + + const clock_t end_clock = clock(); + const double total_seconds = (static_cast<double>(end_clock) - static_cast<double>(start_clock)) / CLOCKS_PER_SEC; + + stream.clear(); + stream.str(""); + stream << "Completed file processing\r\n"; + stream << "\tLines Processed : " << lines_processed_ << "\r\n"; + stream << "\tArc Commands Processed: " << num_arc_commands_ << "\r\n"; + stream << "\tArc Segments Generated: " << p_current_firmware_->get_num_arc_segments_generated() << "\r\n"; + stream << "\tTotal Seconds : " << total_seconds << "\r\n"; + std::cout << stream.str(); +} + +std::string arc_interpolation::get_firmware_argument_description() const +{ + return p_current_firmware_->get_argument_description(); +}
\ No newline at end of file |