//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Arc Welder: Test Application // // This application is only used for ad-hoc testing of the anti-stutter library. // // Built using the 'Arc Welder: Anti Stutter' library // // Copyright(C) 2020 - Brad Hochgesang //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // This program is free software : you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the // GNU Affero General Public License for more details. // // // You can contact the author at the following email address: // FormerLurker@pm.me //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include "ArcWelderTest.h" #include "logger.h" #include #include "utilities.h" int main(int argc, char* argv[]) { run_tests(argc, argv); } int run_tests(int argc, char* argv[]) { _CrtMemState state; // This line will take a snapshot // of the memory allocated at this point. _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); //std::string filename = argv[1]; unsigned int num_runs = 1; _CrtMemCheckpoint(&state); auto start = std::chrono::high_resolution_clock::now(); for (unsigned int index = 0; index < num_runs; index++) { std::cout << "Processing test run " << index + 1 << " of " << num_runs << ".\r\n"; TestAntiStutter(ANTI_STUTTER_TEST); //TestParsingCase(); //TestDoubleToString(); //TestInverseProcessor(); //TestCircularBuffer(); //TestSegmentedLine(); //TestSegmentedArc(); /* if (!TestProblemDoubles()) { std::cout << "Test Failed!" << std::endl; } if (!TestIntToStringRandom(-1000000, 1000000, 1000000)) { std::cout << "Test Failed!" << std::endl; } if (!TestDoubleToStringRandom(-0.5, 0.5, 1000000)) { std::cout << "Test Failed!" << std::endl; } if (!TestDoubleToStringRandom(-100, 100, 1000000)) { std::cout << "Test Failed!" << std::endl; } if (!TestDoubleToStringRandom(-1, 1, 1000000)) { std::cout << "Test Failed!" << std::endl; } if (!TestDoubleToStringRandom(-1000000, 1000000, 1000000)) { std::cout << "Test Failed!" << std::endl; } */ } auto end = std::chrono::high_resolution_clock::now(); _CrtMemDumpAllObjectsSince(&state); std::chrono::duration diff = end - start; std::cout << "Tests completed in " << diff.count() << " seconds"; //std::cout << "Has Memory Leak = " << has_leak << ".\r\n"; // Set the debug-heap flag so that memory leaks are reported when // the process terminates. Then, exit. //printf("Press Any Key to Continue\n"); //std::getchar(); return 0; } static gcode_position_args get_single_extruder_position_args() { gcode_position_args posArgs = gcode_position_args(); posArgs.autodetect_position = true; posArgs.home_x = 0; posArgs.home_x_none = true; posArgs.home_y = 0; posArgs.home_y_none = true; posArgs.home_z = 0; posArgs.home_z_none = true; posArgs.shared_extruder = true; posArgs.zero_based_extruder = true; posArgs.set_num_extruders(1); posArgs.retraction_lengths[0] = .8; posArgs.z_lift_heights[0] = .6; posArgs.x_firmware_offsets[0] = 0; posArgs.y_firmware_offsets[0] = 1; posArgs.default_extruder = 0; posArgs.priming_height = 0.4; posArgs.minimum_layer_height = 0.05; posArgs.height_increment = 0.5; posArgs.g90_influences_extruder = false; posArgs.xyz_axis_default_mode = "absolute"; posArgs.e_axis_default_mode = "absolute"; posArgs.units_default = "millimeters"; posArgs.location_detection_commands = std::vector(); posArgs.is_bound_ = true; posArgs.is_circular_bed = false; posArgs.snapshot_x_min = 0; posArgs.snapshot_x_max = 250; posArgs.snapshot_y_min = 0; posArgs.snapshot_y_max = 210; posArgs.snapshot_z_min = 0; posArgs.snapshot_z_max = 200; posArgs.x_min = 0; posArgs.x_max = 250; posArgs.y_min = -3; posArgs.y_max = 210; posArgs.z_min = 0; posArgs.z_max = 200; return posArgs; } static gcode_position_args get_5_shared_extruder_position_args() { gcode_position_args posArgs = gcode_position_args(); posArgs.autodetect_position = true; posArgs.home_x = 0; posArgs.home_x_none = true; posArgs.home_y = 0; posArgs.home_y_none = true; posArgs.home_z = 0; posArgs.home_z_none = true; posArgs.shared_extruder = true; posArgs.zero_based_extruder = true; posArgs.set_num_extruders(5); posArgs.retraction_lengths[0] = .2; posArgs.retraction_lengths[1] = .4; posArgs.retraction_lengths[2] = .6; posArgs.retraction_lengths[3] = .8; posArgs.retraction_lengths[4] = 1; posArgs.z_lift_heights[0] = 1; posArgs.z_lift_heights[1] = .8; posArgs.z_lift_heights[2] = .6; posArgs.z_lift_heights[3] = .4; posArgs.z_lift_heights[4] = .2; posArgs.x_firmware_offsets[0] = 0; posArgs.y_firmware_offsets[0] = 1; posArgs.x_firmware_offsets[1] = 2; posArgs.y_firmware_offsets[1] = 3; posArgs.x_firmware_offsets[2] = 4; posArgs.y_firmware_offsets[2] = 5; posArgs.x_firmware_offsets[3] = 6; posArgs.y_firmware_offsets[3] = 7; posArgs.x_firmware_offsets[4] = 8; posArgs.y_firmware_offsets[4] = 9; posArgs.default_extruder = 0; posArgs.priming_height = 0.4; posArgs.minimum_layer_height = 0.05; posArgs.g90_influences_extruder = false; posArgs.xyz_axis_default_mode = "absolute"; posArgs.e_axis_default_mode = "absolute"; posArgs.units_default = "millimeters"; posArgs.location_detection_commands = std::vector(); posArgs.is_bound_ = true; posArgs.is_circular_bed = false; posArgs.snapshot_x_min = 0; posArgs.snapshot_x_max = 250; posArgs.snapshot_y_min = 0; posArgs.snapshot_y_max = 210; posArgs.snapshot_z_min = 0; posArgs.snapshot_z_max = 200; posArgs.x_min = 0; posArgs.x_max = 250; posArgs.y_min = -3; posArgs.y_max = 210; posArgs.z_min = 0; posArgs.z_max = 200; return posArgs; } static gcode_position_args get_5_extruder_position_args() { gcode_position_args posArgs = gcode_position_args(); posArgs.autodetect_position = true; posArgs.home_x = 0; posArgs.home_x_none = true; posArgs.home_y = 0; posArgs.home_y_none = true; posArgs.home_z = 0; posArgs.home_z_none = true; posArgs.shared_extruder = false; posArgs.zero_based_extruder = true; posArgs.set_num_extruders(5); posArgs.retraction_lengths[0] = .2; posArgs.retraction_lengths[1] = .4; posArgs.retraction_lengths[2] = .6; posArgs.retraction_lengths[3] = .8; posArgs.retraction_lengths[4] = 1; posArgs.z_lift_heights[0] = 1; posArgs.z_lift_heights[1] = .8; posArgs.z_lift_heights[2] = .6; posArgs.z_lift_heights[3] = .4; posArgs.z_lift_heights[4] = .2; posArgs.x_firmware_offsets[0] = 0; posArgs.y_firmware_offsets[0] = 0; posArgs.x_firmware_offsets[1] = 5; posArgs.y_firmware_offsets[1] = 0; posArgs.x_firmware_offsets[2] = 0; posArgs.y_firmware_offsets[2] = 0; posArgs.x_firmware_offsets[3] = 0; posArgs.y_firmware_offsets[3] = 0; posArgs.x_firmware_offsets[4] = 0; posArgs.y_firmware_offsets[4] = 0; posArgs.default_extruder = 0; posArgs.priming_height = 0.4; posArgs.minimum_layer_height = 0.05; posArgs.g90_influences_extruder = false; posArgs.xyz_axis_default_mode = "absolute"; posArgs.e_axis_default_mode = "absolute"; posArgs.units_default = "millimeters"; posArgs.location_detection_commands = std::vector(); posArgs.is_bound_ = true; posArgs.is_circular_bed = false; posArgs.snapshot_x_min = 0; posArgs.snapshot_x_max = 250; posArgs.snapshot_y_min = 0; posArgs.snapshot_y_max = 210; posArgs.snapshot_z_min = 0; posArgs.snapshot_z_max = 200; posArgs.x_min = 0; posArgs.x_max = 250; posArgs.y_min = -3; posArgs.y_max = 210; posArgs.z_min = 0; posArgs.z_max = 200; return posArgs; } static void TestAntiStutter(std::string filePath) { //double max_resolution = DEFAULT_RESOLUTION_MM; double max_resolution = 0.05; double max_radius_mm = 100000; //int min_arc_segments = DEFAULT_MIN_ARC_SEGMENTS; int min_arc_segments = 0; double mm_per_arc_segment = 0; //double path_tolerance_percent = ARC_LENGTH_PERCENT_TOLERANCE_DEFAULT; // 1 percent double path_tolerance_percent = 0.05; //double path_tolerance_percent = 0.05; std::vector logger_names; logger_names.push_back("arc_welder.gcode_conversion"); std::vector logger_levels; logger_levels.push_back(log_levels::NOSET); logger_levels.push_back(log_levels::VERBOSE); logger_levels.push_back(log_levels::DEBUG); logger_levels.push_back(log_levels::INFO); logger_levels.push_back(log_levels::WARNING); logger_levels.push_back(log_levels::ERROR); logger_levels.push_back(log_levels::CRITICAL); logger* p_logger = new logger(logger_names, logger_levels); p_logger->set_log_level(INFO); //p_logger->set_log_level_by_value(5); //arc_welder arc_welder_obj(BENCHY_0_5_MM_NO_WIPE, "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\test_output.gcode", p_logger, max_resolution, false, 50, static_cast(on_progress)); //arc_welder arc_welder_obj(SIX_SPEED_TEST, "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\test_output.gcode", p_logger, max_resolution, false, 50, on_progress); arc_welder arc_welder_obj( BENCHY_L1_DIFFICULT, "C:\\Users\\Brad\\Documents\\3DPrinter\\AntiStutter\\test_output.gcode", p_logger, max_resolution, path_tolerance_percent, max_radius_mm, min_arc_segments, mm_per_arc_segment, false, true, DEFAULT_ALLOW_DYNAMIC_PRECISION, DEFAULT_XYZ_PRECISION, DEFAULT_E_PRECISION, DEFAULT_GCODE_BUFFER_SIZE, on_progress); //FIRMWARE_COMPENSATION_TEST_1 //BENCHY_MIN_RADIUS_TEST //BENCHY_DIFFICULT //BENCHY_LAYER_1GCODE //SMALL_TEST //FACE_SHIELD //BENCHY_LAYER_1_NO_WIPE //BENCHY_0_5_MM_NO_WIPE //BENCHY_CURA_RELATIVE_E_NOWIPE //BENCHY_GYROID_ABSOLUTE_E_NOWIPEd //BENCHY_GYROID_RELATIVE_E_NOWIPE //BENCHY_STACK_RELATIVE //BENCHY_STACK_ABSOLUTE //FRACTAL //SUPER_HUGE_TEST //TORTURE_TEST //ORCHID_POD //DIFFICULT_CURVES //ISSUE_PRICKLYPEAR_LAYER_0_114 //BARBARIAN // BENCHY_L1_DIFFICULT // SPIRAL_TEST // SPIRAL_VASE_TEST_FUNNEL arc_welder_results results = arc_welder_obj.process(); p_logger->log(0, INFO, results.progress.detail_str()); p_logger->log(0, INFO, "Processing Complete."); delete p_logger; } bool on_progress(arc_welder_progress progress, logger * p_logger, int logger_type) { p_logger->log(logger_type, INFO, progress.str()); return true; } static void TestParsingCase() { gcode_parser parser; //parsed_command command = parser.parse_gcode(" G0 X1 y2 ; test", true); parsed_command command2 = parser.parse_gcode(" M73 P0 R93", true); //parsed_command command2 = parser.parse_gcode("M204 P2000 R1500 T2000 ; sets acceleration (P, T) and retract acceleration (R), mm/sec^2", true); parsed_command command3 = parser.parse_gcode("G0 X1 y2; test", true); } bool TestIntToStringRandom(int low, int high, int num_runs) { bool all_success = true; for (int index = 0; index < num_runs; index++) { int value = utilities::rand_range(low, high); unsigned char precision = utilities::rand_range(static_cast(0), static_cast(6)); if (!CompareDoubleToStringResult(static_cast(value), precision)) { all_success = false; } } return all_success; } bool TestDoubleToStringRandom(double low, double high, int num_runs) { bool all_success = true; for (int index = 0; index < num_runs; index++) { double value = utilities::rand_range(low, high); unsigned char precision = utilities::rand_range(static_cast(0), static_cast(6)); if (!CompareDoubleToStringResult(value, precision)) { all_success = false; } } return all_success; } bool CompareDoubleToStringResult(double value, unsigned char precision) { std::ostringstream stream; stream << std::fixed; stream << std::setprecision(precision) << value; //std::cout << std::fixed << "Testing: " << std::setprecision(12) << value << " precision: " << std::setprecision(0) << static_cast (precision); std::string test_string = utilities::dtos(value, precision); if (test_string != stream.str()) { std::cout << std::fixed << "Failed to convert: " << std::setprecision(24) << value << " Precision:" << std::setprecision(0) << static_cast (precision) << " String:" << test_string << " Stream:" << stream.str() << std::endl; return false; } //std::cout << std::endl; return true; } bool TestProblemDoubles() { bool result = true; result = result && CompareDoubleToStringResult(-0.000030518509475996325, 4); result = result && CompareDoubleToStringResult(0.500000000000000000000000, static_cast(2)); result = result && CompareDoubleToStringResult(9.9999999999999, static_cast(2)); result = result && CompareDoubleToStringResult(9.9950, static_cast(2)); result = result && CompareDoubleToStringResult(39.6, static_cast(3)); result = result && CompareDoubleToStringResult(39.600000000000001421085472, static_cast(3)); result = result && CompareDoubleToStringResult(40.228999999999999204192136, static_cast(3)); return result; }