X-Git-Url: http://git.hcoop.net/clinton/Smoothieware.git/blobdiff_plain/f7fd185d6004e6e3d2be1ba6f00d81c047f0fa18..922f169dba03c9f249a0746dbab0efde0ad10dc1:/src/libs/Kernel.cpp diff --git a/src/libs/Kernel.cpp b/src/libs/Kernel.cpp index 20fef96e..83fe48c2 100644 --- a/src/libs/Kernel.cpp +++ b/src/libs/Kernel.cpp @@ -28,6 +28,11 @@ #include "EndstopsPublicAccess.h" #include "Configurator.h" #include "SimpleShell.h" +#include "TemperatureControlPublicAccess.h" + +#ifndef NO_TOOLS_LASER +#include "Laser.h" +#endif #include "platform_memory.h" @@ -35,6 +40,7 @@ #include #include +#define laser_checksum CHECKSUM("laser") #define baud_rate_setting_checksum CHECKSUM("baud_rate") #define uart0_checksum CHECKSUM("uart0") @@ -42,19 +48,22 @@ #define microseconds_per_step_pulse_checksum CHECKSUM("microseconds_per_step_pulse") #define disable_leds_checksum CHECKSUM("leds_disable") #define grbl_mode_checksum CHECKSUM("grbl_mode") +#define feed_hold_enable_checksum CHECKSUM("enable_feed_hold") #define ok_per_line_checksum CHECKSUM("ok_per_line") Kernel* Kernel::instance; // The kernel is the central point in Smoothie : it stores modules, and handles event calls -Kernel::Kernel(){ - halted= false; - feed_hold= false; +Kernel::Kernel() +{ + halted = false; + feed_hold = false; + enable_feed_hold = false; - instance= this; // setup the Singleton instance of the kernel + instance = this; // setup the Singleton instance of the kernel // serial first at fixed baud rate (DEFAULT_SERIAL_BAUD_RATE) so config can report errors to serial - // Set to UART0, this will be changed to use the same UART as MRI if it's enabled + // Set to UART0, this will be changed to use the same UART as MRI if it's enabled this->serial = new SerialConsole(USBTX, USBRX, DEFAULT_SERIAL_BAUD_RATE); // Config next, but does not load cache yet @@ -65,7 +74,7 @@ Kernel::Kernel(){ // now config is loaded we can do normal setup for serial based on config delete this->serial; - this->serial= NULL; + this->serial = NULL; this->streams = new StreamOutputPool(); @@ -78,35 +87,37 @@ Kernel::Kernel(){ #if MRI_ENABLE != 0 switch( __mriPlatform_CommUartIndex() ) { case 0: - this->serial = new(AHB0) SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); + this->serial = new(AHB0) SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum, baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); break; case 1: - this->serial = new(AHB0) SerialConsole( p13, p14, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); + this->serial = new(AHB0) SerialConsole( p13, p14, this->config->value(uart0_checksum, baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); break; case 2: - this->serial = new(AHB0) SerialConsole( p28, p27, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); + this->serial = new(AHB0) SerialConsole( p28, p27, this->config->value(uart0_checksum, baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); break; case 3: - this->serial = new(AHB0) SerialConsole( p9, p10, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); + this->serial = new(AHB0) SerialConsole( p9, p10, this->config->value(uart0_checksum, baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); break; } #endif // default if(this->serial == NULL) { - this->serial = new(AHB0) SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); + this->serial = new(AHB0) SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum, baud_rate_setting_checksum)->by_default(DEFAULT_SERIAL_BAUD_RATE)->as_number()); } //some boards don't have leds.. TOO BAD! - this->use_leds= !this->config->value( disable_leds_checksum )->by_default(false)->as_bool(); + this->use_leds = !this->config->value( disable_leds_checksum )->by_default(false)->as_bool(); + +#ifdef CNC + this->grbl_mode = this->config->value( grbl_mode_checksum )->by_default(true)->as_bool(); +#else + this->grbl_mode = this->config->value( grbl_mode_checksum )->by_default(false)->as_bool(); +#endif - #ifdef CNC - this->grbl_mode= this->config->value( grbl_mode_checksum )->by_default(true)->as_bool(); - #else - this->grbl_mode= this->config->value( grbl_mode_checksum )->by_default(false)->as_bool(); - #endif + this->enable_feed_hold = this->config->value( feed_hold_enable_checksum )->by_default(this->grbl_mode)->as_bool(); - // we exepct ok per line now not per G code, setting this to false will return to the old (incorrect) way of ok per G code - this->ok_per_line= this->config->value( ok_per_line_checksum )->by_default(true)->as_bool(); + // we expect ok per line now not per G code, setting this to false will return to the old (incorrect) way of ok per G code + this->ok_per_line = this->config->value( ok_per_line_checksum )->by_default(true)->as_bool(); this->add_module( this->serial ); @@ -129,12 +140,12 @@ Kernel::Kernel(){ NVIC_SetPriority(USB_IRQn, 5); // If MRI is enabled - if( MRI_ENABLE ){ - if( NVIC_GetPriority(UART0_IRQn) > 0 ){ NVIC_SetPriority(UART0_IRQn, 5); } - if( NVIC_GetPriority(UART1_IRQn) > 0 ){ NVIC_SetPriority(UART1_IRQn, 5); } - if( NVIC_GetPriority(UART2_IRQn) > 0 ){ NVIC_SetPriority(UART2_IRQn, 5); } - if( NVIC_GetPriority(UART3_IRQn) > 0 ){ NVIC_SetPriority(UART3_IRQn, 5); } - }else{ + if( MRI_ENABLE ) { + if( NVIC_GetPriority(UART0_IRQn) > 0 ) { NVIC_SetPriority(UART0_IRQn, 5); } + if( NVIC_GetPriority(UART1_IRQn) > 0 ) { NVIC_SetPriority(UART1_IRQn, 5); } + if( NVIC_GetPriority(UART2_IRQn) > 0 ) { NVIC_SetPriority(UART2_IRQn, 5); } + if( NVIC_GetPriority(UART3_IRQn) > 0 ) { NVIC_SetPriority(UART3_IRQn, 5); } + } else { NVIC_SetPriority(UART0_IRQn, 5); NVIC_SetPriority(UART1_IRQn, 5); NVIC_SetPriority(UART2_IRQn, 5); @@ -150,9 +161,9 @@ Kernel::Kernel(){ this->step_ticker->set_unstep_time( microseconds_per_step_pulse ); // Core modules + this->add_module( this->conveyor = new Conveyor() ); this->add_module( this->gcode_dispatch = new GcodeDispatch() ); this->add_module( this->robot = new Robot() ); - this->add_module( this->conveyor = new Conveyor() ); this->add_module( this->simpleshell = new SimpleShell() ); this->planner = new Planner(); @@ -165,82 +176,145 @@ std::string Kernel::get_query_string() std::string str; bool homing; bool ok = PublicData::get_value(endstops_checksum, get_homing_status_checksum, 0, &homing); - if(!ok) homing= false; - bool running= false; + if(!ok) homing = false; + bool running = false; str.append("<"); if(halted) { - str.append("Alarm,"); - }else if(homing) { - str.append("Home,"); - }else if(feed_hold) { - str.append("Hold,"); - }else if(this->conveyor->is_idle()) { - str.append("Idle,"); - }else{ - running= true; - str.append("Run,"); + str.append("Alarm"); + } else if(homing) { + running = true; + str.append("Home"); + } else if(feed_hold) { + str.append("Hold"); + } else if(this->conveyor->is_idle()) { + str.append("Idle"); + } else { + running = true; + str.append("Run"); } if(running) { - // get real time current actuator position in mm - ActuatorCoordinates current_position{ - robot->actuators[X_AXIS]->get_current_position(), - robot->actuators[Y_AXIS]->get_current_position(), - robot->actuators[Z_AXIS]->get_current_position() - }; - - // get machine position from the actuator position using FK float mpos[3]; - robot->arm_solution->actuator_to_cartesian(current_position, mpos); + robot->get_current_machine_position(mpos); // current_position/mpos includes the compensation transform so we need to get the inverse to get actual position if(robot->compensationTransform) robot->compensationTransform(mpos, true); // get inverse compensation transform char buf[128]; // machine position - size_t n= snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f,", robot->from_millimeters(mpos[0]), robot->from_millimeters(mpos[1]), robot->from_millimeters(mpos[2])); - str.append("MPos:").append(buf, n); + size_t n = snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f", robot->from_millimeters(mpos[0]), robot->from_millimeters(mpos[1]), robot->from_millimeters(mpos[2])); + if(n > sizeof(buf)) n= sizeof(buf); + + str.append("|MPos:").append(buf, n); + +#if MAX_ROBOT_ACTUATORS > 3 + // deal with the ABC axis (E will be A) + for (int i = A_AXIS; i < robot->get_number_registered_motors(); ++i) { + // current actuator position + n = snprintf(buf, sizeof(buf), ",%1.4f", robot->from_millimeters(robot->actuators[i]->get_current_position())); + if(n > sizeof(buf)) n= sizeof(buf); + str.append(buf, n); + } +#endif // work space position - Robot::wcs_t pos= robot->mcs2wcs(mpos); - n= snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f", robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos))); - str.append("WPos:").append(buf, n); - str.append(">\r\n"); - - }else{ + Robot::wcs_t pos = robot->mcs2wcs(mpos); + n = snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f", robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos))); + if(n > sizeof(buf)) n= sizeof(buf); + + str.append("|WPos:").append(buf, n); + // current feedrate + float fr= robot->from_millimeters(conveyor->get_current_feedrate()*60.0F); + n = snprintf(buf, sizeof(buf), "|F:%1.4f", fr); + if(n > sizeof(buf)) n= sizeof(buf); + str.append(buf, n); + float sr= robot->get_s_value(); + n = snprintf(buf, sizeof(buf), "|S:%1.4f", sr); + if(n > sizeof(buf)) n= sizeof(buf); + str.append(buf, n); + + // current Laser power + #ifndef NO_TOOLS_LASER + Laser *plaser= nullptr; + if(PublicData::get_value(laser_checksum, (void *)&plaser) && plaser != nullptr) { + float lp= plaser->get_current_power(); + n = snprintf(buf, sizeof(buf), "|L:%1.4f", lp); + if(n > sizeof(buf)) n= sizeof(buf); + str.append(buf, n); + } + #endif + + } else { // return the last milestone if idle char buf[128]; // machine position - Robot::wcs_t mpos= robot->get_axis_position(); - size_t n= snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f,", robot->from_millimeters(std::get(mpos)), robot->from_millimeters(std::get(mpos)), robot->from_millimeters(std::get(mpos))); - str.append("MPos:").append(buf, n); + Robot::wcs_t mpos = robot->get_axis_position(); + size_t n = snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f", robot->from_millimeters(std::get(mpos)), robot->from_millimeters(std::get(mpos)), robot->from_millimeters(std::get(mpos))); + if(n > sizeof(buf)) n= sizeof(buf); + + str.append("|MPos:").append(buf, n); + +#if MAX_ROBOT_ACTUATORS > 3 + // deal with the ABC axis (E will be A) + for (int i = A_AXIS; i < robot->get_number_registered_motors(); ++i) { + // current actuator position + n = snprintf(buf, sizeof(buf), ",%1.4f", robot->from_millimeters(robot->actuators[i]->get_current_position())); + if(n > sizeof(buf)) n= sizeof(buf); + str.append(buf, n); + } +#endif // work space position - Robot::wcs_t pos= robot->mcs2wcs(mpos); - n= snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f", robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos))); - str.append("WPos:").append(buf, n); - str.append(">\r\n"); + Robot::wcs_t pos = robot->mcs2wcs(mpos); + n = snprintf(buf, sizeof(buf), "%1.4f,%1.4f,%1.4f", robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos)), robot->from_millimeters(std::get(pos))); + if(n > sizeof(buf)) n= sizeof(buf); + str.append("|WPos:").append(buf, n); + + float fr= robot->from_millimeters(robot->get_feed_rate()); + n = snprintf(buf, sizeof(buf), "|F:%1.4f", fr); + if(n > sizeof(buf)) n= sizeof(buf); + str.append(buf, n); + } + // if not grbl mode get temperatures + if(!is_grbl_mode()) { + struct pad_temperature temp; + // scan all temperature controls + std::vector controllers; + bool ok = PublicData::get_value(temperature_control_checksum, poll_controls_checksum, &controllers); + if (ok) { + char buf[32]; + for (auto &c : controllers) { + size_t n= snprintf(buf, sizeof(buf), "|%s:%1.1f,%1.1f", c.designator.c_str(), c.current_temperature, c.target_temperature); + if(n > sizeof(buf)) n= sizeof(buf); + str.append(buf, n); + } + } } + + str.append(">\n"); return str; } // Add a module to Kernel. We don't actually hold a list of modules we just call its on_module_loaded -void Kernel::add_module(Module* module){ +void Kernel::add_module(Module* module) +{ module->on_module_loaded(); } // Adds a hook for a given module and event -void Kernel::register_for_event(_EVENT_ENUM id_event, Module *mod){ +void Kernel::register_for_event(_EVENT_ENUM id_event, Module *mod) +{ this->hooks[id_event].push_back(mod); } // Call a specific event with an argument -void Kernel::call_event(_EVENT_ENUM id_event, void * argument){ - bool was_idle= true; +void Kernel::call_event(_EVENT_ENUM id_event, void * argument) +{ + bool was_idle = true; if(id_event == ON_HALT) { - this->halted= (argument == nullptr); - was_idle= conveyor->is_idle(); // see if we were doing anything like printing + this->halted = (argument == nullptr); + was_idle = conveyor->is_idle(); // see if we were doing anything like printing } // send to all registered modules @@ -248,9 +322,13 @@ void Kernel::call_event(_EVENT_ENUM id_event, void * argument){ (m->*kernel_callback_functions[id_event])(argument); } - if(id_event == ON_HALT && this->halted && !was_idle) { - // we need to try to correct current positions if we were running - this->robot->reset_position_from_current_actuator_position(); + if(id_event == ON_HALT) { + if(!this->halted || !was_idle) { + // if we were running and this is a HALT + // or if we are clearing the halt with $X or M999 + // fix up the current positions in case they got out of sync due to backed up commands + this->robot->reset_position_from_current_actuator_position(); + } } }