// The Robot converts GCodes into actual movements, and then adds them to the Planner, which passes them to the Conveyor so they can be added to the queue
// It takes care of cutting arcs into segments, same thing for line that are too long
-#define max(a,b) (((a) > (b)) ? (a) : (b))
Robot::Robot()
{
// TODO: delete or detect old steppermotors
// Make our 3 StepperMotors
- this->alpha_stepper_motor = THEKERNEL->step_ticker->add_stepper_motor( new StepperMotor(alpha_step_pin, alpha_dir_pin, alpha_en_pin) );
- this->beta_stepper_motor = THEKERNEL->step_ticker->add_stepper_motor( new StepperMotor(beta_step_pin, beta_dir_pin, beta_en_pin ) );
- this->gamma_stepper_motor = THEKERNEL->step_ticker->add_stepper_motor( new StepperMotor(gamma_step_pin, gamma_dir_pin, gamma_en_pin) );
+ this->alpha_stepper_motor = new StepperMotor(alpha_step_pin, alpha_dir_pin, alpha_en_pin);
+ this->beta_stepper_motor = new StepperMotor(beta_step_pin, beta_dir_pin, beta_en_pin );
+ this->gamma_stepper_motor = new StepperMotor(gamma_step_pin, gamma_dir_pin, gamma_en_pin);
alpha_stepper_motor->change_steps_per_mm(steps_per_mm[0]);
beta_stepper_motor->change_steps_per_mm(steps_per_mm[1]);
gamma_stepper_motor->change_steps_per_mm(steps_per_mm[2]);
- alpha_stepper_motor->max_rate = THEKERNEL->config->value(alpha_max_rate_checksum)->by_default(30000.0F)->as_number() / 60.0F;
- beta_stepper_motor->max_rate = THEKERNEL->config->value(beta_max_rate_checksum )->by_default(30000.0F)->as_number() / 60.0F;
- gamma_stepper_motor->max_rate = THEKERNEL->config->value(gamma_max_rate_checksum)->by_default(30000.0F)->as_number() / 60.0F;
+ alpha_stepper_motor->set_max_rate(THEKERNEL->config->value(alpha_max_rate_checksum)->by_default(30000.0F)->as_number() / 60.0F);
+ beta_stepper_motor->set_max_rate(THEKERNEL->config->value(beta_max_rate_checksum )->by_default(30000.0F)->as_number() / 60.0F);
+ gamma_stepper_motor->set_max_rate(THEKERNEL->config->value(gamma_max_rate_checksum)->by_default(30000.0F)->as_number() / 60.0F);
check_max_actuator_speeds(); // check the configs are sane
actuators.clear();
// we will override the actuator max_rate if the combination of max_rate and steps/sec exceeds base_stepping_frequency
void Robot::check_max_actuator_speeds()
{
- float step_freq= alpha_stepper_motor->max_rate * alpha_stepper_motor->get_steps_per_mm();
+ float step_freq= alpha_stepper_motor->get_max_rate() * alpha_stepper_motor->get_steps_per_mm();
if(step_freq > THEKERNEL->base_stepping_frequency) {
- alpha_stepper_motor->max_rate= floorf(THEKERNEL->base_stepping_frequency / alpha_stepper_motor->get_steps_per_mm());
+ alpha_stepper_motor->set_max_rate(floorf(THEKERNEL->base_stepping_frequency / alpha_stepper_motor->get_steps_per_mm()));
THEKERNEL->streams->printf("WARNING: alpha_max_rate exceeds base_stepping_frequency * alpha_steps_per_mm: %f, setting to %f\n", step_freq, alpha_stepper_motor->max_rate);
}
- step_freq= beta_stepper_motor->max_rate * beta_stepper_motor->get_steps_per_mm();
+ step_freq= beta_stepper_motor->get_max_rate() * beta_stepper_motor->get_steps_per_mm();
if(step_freq > THEKERNEL->base_stepping_frequency) {
- beta_stepper_motor->max_rate= floorf(THEKERNEL->base_stepping_frequency / beta_stepper_motor->get_steps_per_mm());
+ beta_stepper_motor->set_max_rate(floorf(THEKERNEL->base_stepping_frequency / beta_stepper_motor->get_steps_per_mm()));
THEKERNEL->streams->printf("WARNING: beta_max_rate exceeds base_stepping_frequency * beta_steps_per_mm: %f, setting to %f\n", step_freq, beta_stepper_motor->max_rate);
}
- step_freq= gamma_stepper_motor->max_rate * gamma_stepper_motor->get_steps_per_mm();
+ step_freq= gamma_stepper_motor->get_max_rate() * gamma_stepper_motor->get_steps_per_mm();
if(step_freq > THEKERNEL->base_stepping_frequency) {
- gamma_stepper_motor->max_rate= floorf(THEKERNEL->base_stepping_frequency / gamma_stepper_motor->get_steps_per_mm());
+ gamma_stepper_motor->set_max_rate(floorf(THEKERNEL->base_stepping_frequency / gamma_stepper_motor->get_steps_per_mm()));
THEKERNEL->streams->printf("WARNING: gamma_max_rate exceeds base_stepping_frequency * gamma_steps_per_mm: %f, setting to %f\n", step_freq, gamma_stepper_motor->max_rate);
}
}
if (gcode->has_letter('Z'))
this->max_speeds[Z_AXIS] = gcode->get_value('Z');
if (gcode->has_letter('A'))
- alpha_stepper_motor->max_rate = gcode->get_value('A');
+ alpha_stepper_motor->set_max_rate(gcode->get_value('A'));
if (gcode->has_letter('B'))
- beta_stepper_motor->max_rate = gcode->get_value('B');
+ beta_stepper_motor->set_max_rate(gcode->get_value('B'));
if (gcode->has_letter('C'))
- gamma_stepper_motor->max_rate = gcode->get_value('C');
+ gamma_stepper_motor->set_max_rate(gcode->get_value('C'));
check_max_actuator_speeds();
gcode->stream->printf("X:%g Y:%g Z:%g A:%g B:%g C:%g ",
this->max_speeds[X_AXIS], this->max_speeds[Y_AXIS], this->max_speeds[Z_AXIS],
- alpha_stepper_motor->max_rate, beta_stepper_motor->max_rate, gamma_stepper_motor->max_rate);
+ alpha_stepper_motor->get_max_rate(), beta_stepper_motor->get_max_rate(), gamma_stepper_motor->get_max_rate());
gcode->add_nl = true;
gcode->mark_as_taken();
break;
gcode->mark_as_taken();
if (gcode->has_letter('S')) {
- // TODO for safety so it applies only to following gcodes, maybe a better way to do this?
- THEKERNEL->conveyor->wait_for_empty_queue();
float acc = gcode->get_value('S'); // mm/s^2
// enforce minimum
if (acc < 1.0F)
THEKERNEL->planner->acceleration = acc;
}
if (gcode->has_letter('Z')) {
- // TODO for safety so it applies only to following gcodes, maybe a better way to do this?
- THEKERNEL->conveyor->wait_for_empty_queue();
float acc = gcode->get_value('Z'); // mm/s^2
// enforce positive
if (acc < 0.0F)
}
break;
- case 205: // M205 Xnnn - set junction deviation, Z - set Z junction deviation, Snnn - Set minimum planner speed
+ case 205: // M205 Xnnn - set junction deviation, Z - set Z junction deviation, Snnn - Set minimum planner speed, Ynnn - set minimum step rate
gcode->mark_as_taken();
if (gcode->has_letter('X')) {
float jd = gcode->get_value('X');
mps = 0.0F;
THEKERNEL->planner->minimum_planner_speed = mps;
}
+ if (gcode->has_letter('Y')) {
+ alpha_stepper_motor->default_minimum_actuator_rate = gcode->get_value('Y');
+ }
break;
case 220: // M220 - speed override percentage
case 503: { // M503 just prints the settings
gcode->stream->printf(";Steps per unit:\nM92 X%1.5f Y%1.5f Z%1.5f\n", actuators[0]->steps_per_mm, actuators[1]->steps_per_mm, actuators[2]->steps_per_mm);
gcode->stream->printf(";Acceleration mm/sec^2:\nM204 S%1.5f Z%1.5f\n", THEKERNEL->planner->acceleration, THEKERNEL->planner->z_acceleration);
- gcode->stream->printf(";X- Junction Deviation, Z- Z junction deviation, S - Minimum Planner speed:\nM205 X%1.5f Z%1.5f S%1.5f\n", THEKERNEL->planner->junction_deviation, THEKERNEL->planner->z_junction_deviation, THEKERNEL->planner->minimum_planner_speed);
+ gcode->stream->printf(";X- Junction Deviation, Z- Z junction deviation, S - Minimum Planner speed mm/sec:\nM205 X%1.5f Z%1.5f S%1.5f\n", THEKERNEL->planner->junction_deviation, THEKERNEL->planner->z_junction_deviation, THEKERNEL->planner->minimum_planner_speed);
gcode->stream->printf(";Max feedrates in mm/sec, XYZ cartesian, ABC actuator:\nM203 X%1.5f Y%1.5f Z%1.5f A%1.5f B%1.5f C%1.5f\n",
this->max_speeds[X_AXIS], this->max_speeds[Y_AXIS], this->max_speeds[Z_AXIS],
- alpha_stepper_motor->max_rate, beta_stepper_motor->max_rate, gamma_stepper_motor->max_rate);
+ alpha_stepper_motor->get_max_rate(), beta_stepper_motor->get_max_rate(), gamma_stepper_motor->get_max_rate());
// get or save any arm solution specific optional values
BaseSolution::arm_options_t options;
arm_solution->set_optional(options);
}
- // set delta segments per second, not saved by M500
- if(gcode->has_letter('S')) {
+
+ if(gcode->has_letter('S')) { // set delta segments per second, not saved by M500
this->delta_segments_per_second = gcode->get_value('S');
+ gcode->stream->printf("Delta segments set to %8.4f segs/sec\n", this->delta_segments_per_second);
+
+ }else if(gcode->has_letter('U')) { // or set mm_per_line_segment, not saved by M500
+ this->mm_per_line_segment = gcode->get_value('U');
+ this->delta_segments_per_second = 0;
+ gcode->stream->printf("mm per line segment set to %8.4f\n", this->mm_per_line_segment);
}
+
break;
}
}
for (int actuator = 0; actuator <= 2; actuator++) {
float actuator_rate = fabs(actuator_pos[actuator] - actuators[actuator]->last_milestone_mm) * rate_mm_s / millimeters_of_travel;
- if (actuator_rate > actuators[actuator]->max_rate)
- rate_mm_s *= (actuators[actuator]->max_rate / actuator_rate);
+ if (actuator_rate > actuators[actuator]->get_max_rate())
+ rate_mm_s *= (actuators[actuator]->get_max_rate() / actuator_rate);
}
// Append the block to the planner
// the faster the travel speed the fewer segments needed
// NOTE rate is mm/sec and we take into account any speed override
float seconds = gcode->millimeters_of_travel / rate_mm_s;
- segments = max(1, ceil(this->delta_segments_per_second * seconds));
+ segments = max(1.0F, ceilf(this->delta_segments_per_second * seconds));
// TODO if we are only moving in Z on a delta we don't really need to segment at all
} else {
if(this->mm_per_line_segment == 0.0F) {
segments = 1; // don't split it up
} else {
- segments = ceil( gcode->millimeters_of_travel / this->mm_per_line_segment);
+ segments = ceilf( gcode->millimeters_of_travel / this->mm_per_line_segment);
}
}
this->distance_in_gcode_is_known( gcode );
// Figure out how many segments for this gcode
- uint16_t segments = floor(gcode->millimeters_of_travel / this->mm_per_arc_segment);
+ uint16_t segments = floorf(gcode->millimeters_of_travel / this->mm_per_arc_segment);
float theta_per_segment = angular_travel / segments;
float linear_per_segment = linear_travel / segments;