LinuxCNC S-разгон и торможение
- Nick
- Мастер
- Сообщения: 22776
- Зарегистрирован: 23 ноя 2009, 16:45
- Репутация: 1735
- Заслуга: Developer
- Откуда: Gatchina, Saint-Petersburg distr., Russia
- Контактная информация:
LinuxCNC S-разгон и торможение
В воздухе летает настойчивая мысль реализовать таки S-разгон в LinuxCNC.
Вроде как уже есть что-то подобное:
https://github.com/araisrobo/linuxcnc/b ... s/tp.c#808
Но мне кажется что-то они с этой функцией намудрили...
В связи с этим есть желание самому разобраться, где бы почитать про функции, которые надо переписать для реализации S-разгона?
Насколько я понимаю надо переписать планировщик скоростей и сглаживатель траекторий.
Вроде как уже есть что-то подобное:
https://github.com/araisrobo/linuxcnc/b ... s/tp.c#808
Но мне кажется что-то они с этой функцией намудрили...
В связи с этим есть желание самому разобраться, где бы почитать про функции, которые надо переписать для реализации S-разгона?
Насколько я понимаю надо переписать планировщик скоростей и сглаживатель траекторий.
- Nick
- Мастер
- Сообщения: 22776
- Зарегистрирован: 23 ноя 2009, 16:45
- Репутация: 1735
- Заслуга: Developer
- Откуда: Gatchina, Saint-Petersburg distr., Russia
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
Что намудрили с функцией разгона Araisrobo:
Было:
Т.е. простое вычисление ускорения и скорости для нормального движения исходя из текущей и максимальной скорости, ускорения, положения и заданного положения.
Стало:
Каких-то 6 различных случая для ускорения , и вообще все как-то очень длинно и сложно.
По идее, все, что нам надо - ввести еще один параметр для оси - a2 - максимальное изменение ускорения. Тогда функция перемещения будет
PT = P0 + V*T + 1/2A*T^2 + 1/6A2*T^3
Т.е. имеем уравнение 3-й степени от T, которое можно решить. Зачем все эти 6 разных случаев???
Было:
Код: Выделить всё
void tcRunCycle(TP_STRUCT *tp, TC_STRUCT *tc, double *v, int *on_final_decel) {
double discr, maxnewvel, newvel, newaccel=0;
if(!tc->blending) tc->vel_at_blend_start = tc->currentvel;
discr = 0.5 * tc->cycle_time * tc->currentvel - (tc->target - tc->progress);
if(discr > 0.0) {
// should never happen: means we've overshot the target
newvel = maxnewvel = 0.0;
} else {
discr = 0.25 * pmSq(tc->cycle_time) - 2.0 / tc->maxaccel * discr;
newvel = maxnewvel = -0.5 * tc->maxaccel * tc->cycle_time + tc->maxaccel * pmSqrt(discr);
}
if(newvel <= 0.0) {
// also should never happen - if we already finished this tc, it was
// caught above
newvel = newaccel = 0.0;
tc->progress = tc->target;
} else {
// constrain velocity
if(newvel > tc->reqvel * tc->feed_override) newvel = tc->reqvel * tc->feed_override;
if(newvel > tc->maxvel) newvel = tc->maxvel;
// if the motion is not purely rotary axes (and therefore in angular units) ...
if(!(tc->motion_type == TC_LINEAR && tc->coords.line.xyz.tmag_zero && tc->coords.line.uvw.tmag_zero)) {
// ... clamp motion's velocity at TRAJ MAX_VELOCITY (tooltip maxvel)
// except when it's synced to spindle position.
if((!tc->synchronized || tc->velocity_mode) && newvel > tp->vLimit) {
newvel = tp->vLimit;
}
}
// get resulting acceleration
newaccel = (newvel - tc->currentvel) / tc->cycle_time;
// constrain acceleration and get resulting velocity
if(newaccel > 0.0 && newaccel > tc->maxaccel) {
newaccel = tc->maxaccel;
newvel = tc->currentvel + newaccel * tc->cycle_time;
}
if(newaccel < 0.0 && newaccel < -tc->maxaccel) {
newaccel = -tc->maxaccel;
newvel = tc->currentvel + newaccel * tc->cycle_time;
}
// update position in this tc
tc->progress += (newvel + tc->currentvel) * 0.5 * tc->cycle_time;
}
tc->currentvel = newvel;
if(v) *v = newvel;
if(on_final_decel) *on_final_decel = fabs(maxnewvel - newvel) < 0.001;
}
Стало:
Код: Выделить всё
/*
Continuous form
PT = P0 + V0T + 1/2A0T2 + 1/6JT3
VT = V0 + A0T + 1/2 JT2
AT = A0 + JT
Discrete time form (let T be 1, then T^2 == 1, T^3 == 1)
PT = PT + VT + 1/2AT + 1/6J
VT = VT + AT + 1/2JT
AT = AT + JT
*/
/**
* S-curve Velocity Profiler FSM
* Yishin Li <ysli@araisrobo.com>
* ARAIS ROBOT TECHNOLOGY, http://www.araisrobo.com/
**/
void tcRunCycle(TP_STRUCT *tp, TC_STRUCT *tc)
{
double t, t1, vel, v1, dist, req_vel;
int immediate_state;
double tc_target;
if(tc->seamless_blend_mode == SMLBLND_ENABLE) {
tc_target = tc->target + tc->nexttc_target;
} else {
tc_target = tc->target;
}
immediate_state = 0;
do {
switch (tc->accel_state) {
case ACCEL_S0:
// AT = AT + JT
// VT = VT + AT + 1/2JT
// PT = PT + VT + 1/2AT + 1/6JT
tc->cur_accel = tc->cur_accel + tc->jerk;
tc->cur_vel = tc->cur_vel + tc->cur_accel + 0.5 * tc->jerk;
tc->progress = tc->progress + tc->cur_vel + 0.5 * tc->cur_accel + 1.0/6.0 * tc->jerk;
// check if we hit accel limit at next BP
if ((tc->cur_accel + tc->jerk) >= tc->maxaccel) {
tc->cur_accel = tc->maxaccel;
tc->accel_state = ACCEL_S1;
break;
}
// check if we will hit velocity limit;
// assume we start decel from here to "accel == 0"
//
// AT = A0 + JT (let AT = 0 to calculate T)
// VT = V0 + A0T + 1/2JT2
t = ceil(tc->cur_accel / tc->jerk);
req_vel = tc->reqvel * tc->feed_override * tc->cycle_time;
if (req_vel > tc->maxvel) {
req_vel = tc->maxvel;
}
vel = req_vel - tc->cur_accel * t + 0.5 * tc->jerk * t * t;
if (tc->cur_vel >= vel) {
tc->accel_state = ACCEL_S2;
break;
}
// check if we will hit progress limit
// AT = AT + JT
// VT = V0 + A0T + 1/2 JT^2
// PT = P0 + V0T + 1/2A0T^2 + 1/6JT^3
// distance for S2
t = ceil(tc->cur_accel/tc->jerk);
dist = tc->progress + tc->cur_vel * t + 0.5 * tc->cur_accel * t * t
- 1.0/6.0 * tc->jerk * t * t * t;
vel = tc->cur_vel + tc->cur_accel * t - 0.5 * tc->jerk * t * t;
// distance for S3
dist += (vel);
/*
0.5 * vel = vel + 0 * t1 - 0.5 * j * t1 * t1;
t1 = sqrt(vel/j)
*/
t = ceil(sqrt(vel/tc->jerk));
// AT = AT + JT
t1 = ceil(tc->maxaccel / tc->jerk); // max time for S4
if (t > t1) {
// S4 -> S5 -> S6
dist += t1 * vel; // dist of (S4 + S6)
// calc decel.dist for ACCEL_S5
// t: time for S5
t = (vel - tc->jerk * t1 * t1) / tc->maxaccel;
v1 = vel - 0.5 * tc->jerk * t1 * t1;
// PT = P0 + V0T + 1/2A0T^2 + 1/6JT^3
dist += (v1 * t - 0.5 * tc->maxaccel * t * t);
} else {
// S4 -> S6
dist += t * vel; // dist of (S4 + S6)
}
if (tc_target < dist) {
tc->accel_state = ACCEL_S2;
break;
}
break;
case ACCEL_S1:
// jerk is 0 at this state
// VT = VT + AT + 1/2JT
// PT = PT + VT + 1/2AT + 1/6JT
tc->cur_vel = tc->cur_vel + tc->cur_accel;
tc->progress = tc->progress + tc->cur_vel + 0.5 * tc->cur_accel;
// check if we will hit velocity limit;
// assume we start decel from here to "accel == 0"
//
// AT = A0 + JT (let AT = 0 to calculate T)
// VT = V0 + A0T + 1/2JT2
// t = ceil(tc->cur_accel / tc->jerk);
t = tc->cur_accel / tc->jerk;
req_vel = tc->reqvel * tc->feed_override * tc->cycle_time;
if (req_vel > tc->maxvel) {
req_vel = tc->maxvel;
}
vel = req_vel - tc->cur_accel * t + 0.5 * tc->jerk * t * t;
if (tc->cur_vel >= vel) {
tc->accel_state = ACCEL_S2;
break;
}
// check if we will hit progress limit
// distance for S2
t = ceil(tc->cur_accel/tc->jerk);
dist = tc->progress + tc->cur_vel * t + 0.5 * tc->cur_accel * t * t
- 1.0/6.0 * tc->jerk * t * t * t;
vel = tc->cur_vel + tc->cur_accel * t - 0.5 * tc->jerk * t * t;
// distance for S3
dist += (vel);
/*
0.5 * vel = vel + 0 * t1 - 0.5 * j * t1 * t1;
t1 = sqrt(vel/j)
*/
t = ceil(sqrt(vel/tc->jerk));
// AT = AT + JT
t1 = ceil(tc->maxaccel / tc->jerk); // max time for S4
if (t > t1) {
// S4 -> S5 -> S6
dist += t1 * vel; // dist of (S4 + S6)
// calc decel.dist for ACCEL_S5
// t: time for S5
t = (vel - tc->jerk * t1 * t1) / tc->maxaccel;
v1 = vel - 0.5 * tc->jerk * t1 * t1;
// PT = P0 + V0T + 1/2A0T^2 + 1/6JT^3
dist += (v1 * t - 0.5 * tc->maxaccel * t * t);
} else {
// S4 -> S6
dist += t * vel; // dist of (S4 + S6)
}
if (tc_target < dist) {
tc->accel_state = ACCEL_S2;
break;
}
break;
case ACCEL_S2:
// to DECELERATE to ACCEL==0
// AT = AT + JT
// VT = VT + AT + 1/2JT
// PT = PT + VT + 1/2AT + 1/6JT
tc->cur_accel = tc->cur_accel - tc->jerk;
tc->cur_vel = tc->cur_vel + tc->cur_accel - 0.5 * tc->jerk;
tc->progress = tc->progress + tc->cur_vel + 0.5 * tc->cur_accel - 1.0/6.0 * tc->jerk;
// check accel == 0
if (tc->cur_accel <= 0) {
tc->accel_state = ACCEL_S3;
break;
}
// check if we will hit velocity limit at next BP
req_vel = tc->reqvel * tc->feed_override * tc->cycle_time;
if (req_vel > tc->maxvel) {
req_vel = tc->maxvel;
}
// vel: velocity at next BP
vel = tc->cur_vel + tc->cur_accel - 1.5 * tc->jerk;
if (vel > req_vel) {
tc->cur_vel = vel;
tc->accel_state = ACCEL_S3;
break;
}
// check if we will hit progress limit
// refer to 2011-10-17 ysli design note
// AT = AT + JT
// VT = V0 + A0T + 1/2 JT^2
// PT = P0 + V0T + 1/2A0T^2 + 1/6JT^3
vel = tc->cur_vel;
// distance for S3
dist = tc->progress + (vel);
/*
0.5 * vel = vel + 0 * t1 - 0.5 * j * t1 * t1;
t1 = sqrt(vel/j)
*/
t = ceil(sqrt(vel/tc->jerk));
// AT = AT + JT
t1 = ceil(tc->maxaccel / tc->jerk); // max time for S4
if (t > t1) {
// S4 -> S5 -> S6
dist += t1 * vel; // dist of (S4 + S6)
// calc decel.dist for ACCEL_S5
// t: time for S5
t = (vel - tc->jerk * t1 * t1) / tc->maxaccel;
v1 = vel - 0.5 * tc->jerk * t1 * t1;
// PT = P0 + V0T + 1/2A0T^2 + 1/6JT^3
dist += (v1 * t - 0.5 * tc->maxaccel * t * t);
} else {
// S4 -> S6
dist += t * vel; // dist of (S4 + S6)
}
if (tc_target < dist) {
tc->accel_state = ACCEL_S3;
break;
}
break;
case ACCEL_S3:
// PT = PT + VT + 1/2AT + 1/6JT
// , where (jerk == 0) and (accel == 0)
tc->cur_accel = 0;
tc->progress = tc->progress + tc->cur_vel;
// check if we will hit progress limit
// refer to 2011-10-17 ysli design note
// AT = AT + JT
// VT = V0 + A0T + 1/2 JT^2
// PT = P0 + V0T + 1/2A0T^2 + 1/6JT^3
/*
0.5 * vel = vel + 0 * t1 - 0.5 * j * t1 * t1;
t1 = sqrt(vel/j)
*/
vel = tc->cur_vel;
// t = floor(sqrt(vel/tc->jerk) - 0.5);
t = sqrt(vel/tc->jerk);
// t = sqrt(vel/tc->jerk);
// AT = AT + JT
// t1 = floor(tc->maxaccel / tc->jerk - 0.5); // max time for S4
t1 = tc->maxaccel / tc->jerk; // max time for S4
// t1 = tc->maxaccel / tc->jerk; // max time for S4
if (t > t1) {
// S4 -> S5 -> S6
dist = tc->progress + t1 * vel; // dist of (S4 + S6)
// calc decel.dist for ACCEL_S5
// t: time for S5
// t = floor((vel - tc->maxaccel * t1) / tc->maxaccel - 0.5);
t = (vel - tc->maxaccel * t1) / tc->maxaccel - 0.5;
// t = (vel - tc->maxaccel * t1) / tc->maxaccel;
v1 = vel - 0.5 * tc->jerk * t1 * t1;
// PT = P0 + V0T + 1/2A0T^2 + 1/6JT^3
dist += (v1 * t - 0.5 * tc->maxaccel * t * t);
} else {
// S4 -> S6
dist = tc->progress + t * vel; // dist of (S4 + S6)
}
// check if dist would be greater than tc_target at next cycle
if (tc_target < (dist - vel)) {
tc->accel_state = ACCEL_S4;
// blending at largest velocity for G64 w/o P<tolerance>
if (!tc->tolerance) {
tc->tolerance = tc->target - tc->progress; // tc->distance_to_go
}
break;
}
// check for changes of feed_override and request-velocity
req_vel = tc->reqvel * tc->feed_override * tc->cycle_time;
if (req_vel > tc->maxvel) {
req_vel = tc->maxvel;
}
if ((tc->cur_vel + 1.5 * tc->jerk) < req_vel) {
tc->accel_state = ACCEL_S0;
break;
} else if ((tc->cur_vel - 1.5 * tc->jerk) > req_vel) {
tc->accel_state = ACCEL_S4;
break;
}
tc->cur_vel = req_vel;
break;
case ACCEL_S4:
// AT = AT + JT
// VT = VT + AT + 1/2JT
// PT = PT + VT + 1/2AT + 1/6JT
tc->cur_accel = tc->cur_accel - tc->jerk;
tc->cur_vel = tc->cur_vel + tc->cur_accel - 0.5 * tc->jerk;
if (tc->cur_vel <= 0) {
tc->cur_vel = 0;
tc->accel_state = ACCEL_S3;
break;
}
tc->progress = tc->progress + tc->cur_vel + 0.5 * tc->cur_accel - 1.0/6.0 * tc->jerk;
// (accel < 0) and (jerk < 0)
assert (tc->cur_accel < 0);
// check if we hit accel limit at next BP
if ((tc->cur_accel - tc->jerk) <= -tc->maxaccel) {
tc->cur_accel = -tc->maxaccel;
tc->accel_state = ACCEL_S5;
break;
}
// should we stay in S4 and keep decel?
// calculate dist for S6 -> S4 -> (maybe S5) -> S6
t = - tc->cur_accel / tc->jerk;
// target dist after switching to S6 (jerk is positive for S6)
dist = tc->progress + tc->cur_vel * t
+ 0.5 * tc->cur_accel * t * t
+ 1.0 / 6.0 * tc->jerk * t * t * t;
// VT = V0 + A0T + 1/2JT2
// obtain vel for S6 -> S3
vel = tc->cur_vel + tc->cur_accel * t + 0.5 * tc->jerk * t * t;
if (vel > 0) {
/*
0.5 * vel = vel + 0 * t1 - 0.5 * j * t1 * t1;
t1 = sqrt(vel/j)
*/
t = ceil(sqrt(vel/tc->jerk));
// AT = AT + JT
t1 = ceil(tc->maxaccel / tc->jerk); // max time for S4
if (t > t1) {
// S4 -> S5 -> S6
dist += t1 * vel; // dist of (S4 + S6)
// calc decel.dist for ACCEL_S5
// t: time for S5
t = (vel - tc->jerk * t1 * t1) / tc->maxaccel;
v1 = vel - 0.5 * tc->jerk * t1 * t1;
// PT = P0 + V0T + 1/2A0T^2 + 1/6JT^3
dist += (v1 * t - 0.5 * tc->maxaccel * t * t);
} else {
// S4 -> S6
dist += t * vel; // dist of (S4 + S6)
}
}
// check if dist would be greater than tc_target at next cycle
if (tc_target < (dist - (tc->cur_vel + 1.5 * tc->cur_accel - 2.1666667 * tc->jerk))) {
tc->accel_state = ACCEL_S4;
DPS("should stay in S4 and keep decel\n");
break;
}
// check if we will approaching requested velocity
// vel should not be greater than "request velocity" after
// starting acceleration to "accel == 0".
//
// AT = A0 + JT (let AT = 0 to calculate T)
// VT = V0 + A0T + 1/2JT2
t = - tc->cur_accel / tc->jerk;
req_vel = tc->reqvel * tc->feed_override * tc->cycle_time;
if (req_vel > tc->maxvel) {
req_vel = tc->maxvel;
}
if ((tc->cur_vel + tc->cur_accel * t + 0.5 * tc->jerk * t * t) <= req_vel) {
tc->accel_state = ACCEL_S6;
DPS("S4: hit velocity rule; move to S6\n");
break;
}
break;
case ACCEL_S5:
// jerk is 0 at this state
// accel < 0
// VT = VT + AT + 1/2JT
// PT = PT + VT + 1/2AT + 1/6JT
tc->cur_vel = tc->cur_vel + tc->cur_accel;
tc->progress = tc->progress + tc->cur_vel + 0.5 * tc->cur_accel;
// should we stay in S5 and keep decel?
// calculate dist for S6 -> S4 -> (maybe S5) -> S6
t = - tc->cur_accel / tc->jerk;
// target dist after switching to S6 (jerk is positive for S6)
dist = tc->progress + tc->cur_vel * t
+ 0.5 * tc->cur_accel * t * t
+ 1.0 / 6.0 * tc->jerk * t * t * t;
// VT = V0 + A0T + 1/2JT2
// obtain vel for S6 -> S3
vel = tc->cur_vel + tc->cur_accel * t + 0.5 * tc->jerk * t * t;
if (vel > 0) {
/* S6 -> S3 -> S4 -> S5(maybe) -> S6 */
/*
0.5 * vel = vel + 0 * t1 - 0.5 * j * t1 * t1;
t1 = sqrt(vel/j)
*/
t = ceil(sqrt(vel/tc->jerk));
// AT = AT + JT
t1 = ceil(tc->maxaccel / tc->jerk); // max time for S4
if (t > t1) {
// S4 -> S5 -> S6
dist += t1 * vel; // dist of (S4 + S6)
// calc decel.dist for ACCEL_S5
// t: time for S5
t = (vel - tc->jerk * t1 * t1) / tc->maxaccel;
v1 = vel - 0.5 * tc->jerk * t1 * t1;
// PT = P0 + V0T + 1/2A0T^2 + 1/6JT^3
dist += (v1 * t - 0.5 * tc->maxaccel * t * t);
} else {
// S4 -> S6
dist += t * vel; // dist of (S4 + S6)
}
}
// check if dist would be greater than tc_target at next cycle
if (tc_target < (dist - (tc->cur_vel + 1.5 * tc->cur_accel))) {
tc->accel_state = ACCEL_S5;
DPS("should stay in S5 and keep decel\n");
break;
}
// check if we will approaching requested velocity
// vel should not be greater than "request velocity" after
// starting acceleration to "accel == 0".
//
// AT = A0 + JT (let AT = 0 to calculate T)
// VT = V0 + A0T + 1/2JT2
// t: cycles for accel to decel to 0
t = - tc->cur_accel / tc->jerk;
req_vel = tc->reqvel * tc->feed_override * tc->cycle_time;
if (req_vel > tc->maxvel) {
req_vel = tc->maxvel;
}
if ((tc->cur_vel + tc->cur_accel * t + 0.5 * tc->jerk * t * t) <= req_vel) {
tc->accel_state = ACCEL_S6;
break;
}
break;
case ACCEL_S6:
// AT = AT + JT
// VT = VT + AT + 1/2JT
// PT = PT + VT + 1/2AT + 1/6JT
tc->cur_accel = tc->cur_accel + tc->jerk;
tc->cur_vel = tc->cur_vel + tc->cur_accel + 0.5 * tc->jerk;
if (tc->cur_vel <= 0) {
tc->cur_accel = 0;
tc->cur_vel = 0.5 * tc->jerk; // give some velocity for approaching target
}
dist = tc->cur_vel + 0.5 * tc->cur_accel + 1.0/6.0 * tc->jerk;
tc->progress = tc->progress + dist;
if (tc->cur_accel >= 0) {
tc->accel_state = ACCEL_S3;
}
break;
default:
assert(0);
} // switch (tc->accel_state)
} while (immediate_state);
if (tc->seamless_blend_mode != SMLBLND_ENABLE) {
if (tc->progress >= tc->target) {
// finished
// DPS("hit target, cur_accel(%f), cur_vel(%f)\n", tc->cur_accel, tc->cur_vel);
tc->progress = tc->target;
tc->cur_accel = 0;
tc->cur_vel = 0;
}
}
DPS("%11u%6d%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f%15.5f\n",
_dt, tc->accel_state, tc->reqvel * tc->feed_override * tc->cycle_time,
tc->cur_accel, tc->cur_vel, tc->progress/tc->target, tc->target,
(tc->target - tc->progress), tc_target);
tc->distance_to_go = tc->target - tc->progress;
//TODO: this assert will be triggered with rockman.ini:
// assert (tc->cur_vel >= 0);
}
По идее, все, что нам надо - ввести еще один параметр для оси - a2 - максимальное изменение ускорения. Тогда функция перемещения будет
PT = P0 + V*T + 1/2A*T^2 + 1/6A2*T^3
Т.е. имеем уравнение 3-й степени от T, которое можно решить. Зачем все эти 6 разных случаев???
-
- Зачётный участник
- Сообщения: 34042
- Зарегистрирован: 04 апр 2010, 19:22
- Репутация: 6192
- Откуда: Казахстан.
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
Nick писал(а):В воздухе летает настойчивая мысль реализовать таки S-разгон в LinuxCNC.
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
- tooshka
- Почётный участник
- Сообщения: 1803
- Зарегистрирован: 24 окт 2012, 14:26
- Репутация: 209
- Настоящее имя: Андрей
- Откуда: Нижний Новгород
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
не только это, а еще голова разболелась от попыток понять)))Nick писал(а): вообще все как-то очень длинно и сложно.
Милая, ты услышь меня
под окном стою со своим я ЧПУ! (Протяжно; с надрывом; форте)
Внимание!!! Чрезмерное увлечение ЧПУ приводит к проблемам в семейных отношениях!
под окном стою со своим я ЧПУ! (Протяжно; с надрывом; форте)
Внимание!!! Чрезмерное увлечение ЧПУ приводит к проблемам в семейных отношениях!
- Starik
- Опытный
- Сообщения: 136
- Зарегистрирован: 13 май 2012, 21:22
- Репутация: 17
- Откуда: Долгопрудный
Re: LinuxCNC S-разгон и торможение
Вот статья примерно об том же, может помочь с пониманием:
- tooshka
- Почётный участник
- Сообщения: 1803
- Зарегистрирован: 24 окт 2012, 14:26
- Репутация: 209
- Настоящее имя: Андрей
- Откуда: Нижний Новгород
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
*3,14 скорее поможетaystarik писал(а):может помочь с пониманием:
Милая, ты услышь меня
под окном стою со своим я ЧПУ! (Протяжно; с надрывом; форте)
Внимание!!! Чрезмерное увлечение ЧПУ приводит к проблемам в семейных отношениях!
под окном стою со своим я ЧПУ! (Протяжно; с надрывом; форте)
Внимание!!! Чрезмерное увлечение ЧПУ приводит к проблемам в семейных отношениях!
- Nick
- Мастер
- Сообщения: 22776
- Зарегистрирован: 23 ноя 2009, 16:45
- Репутация: 1735
- Заслуга: Developer
- Откуда: Gatchina, Saint-Petersburg distr., Russia
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
Да, статья хорошая, надо будет по подробнее ее изучить. Пока навскидку не совсем понятно зачем делить на 7 случаев, понятно, что у нас есть 7 различных "вариантов" движения, но все это все равно описывается одой единственной функцией...
- Starik
- Опытный
- Сообщения: 136
- Зарегистрирован: 13 май 2012, 21:22
- Репутация: 17
- Откуда: Долгопрудный
Re: LinuxCNC S-разгон и торможение
А они машину семи состояний сделали... типа для разгона одно, для торможения -- другое, для круиза третье... только тут еще набор/сброс ускорения добавился...
- Сергей Саныч
- Мастер
- Сообщения: 9116
- Зарегистрирован: 30 май 2012, 14:20
- Репутация: 2857
- Откуда: Тюмень
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
- А давай заведем новую переменную!
- Сам за ней ухаживать будешь?
Если я правильно понял, там рассматривается куча возникающих ограничений - по максимальному ускорению, скорости, достижению требуемой позиции. Кроме того, учитывается, что время тут дискретно.
Чудес не бывает. Бывают фокусы.
- PKM
- Почётный участник
- Сообщения: 4263
- Зарегистрирован: 31 мар 2011, 18:11
- Репутация: 705
- Настоящее имя: Андрей
- Откуда: Украина
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
Вот это было бы шикарно!Nick писал(а):В воздухе летает настойчивая мысль реализовать таки S-разгон в LinuxCNC.
Интересно, оно работает? Почему его не вносят в тестовые версии?Nick писал(а):Вроде как уже есть что-то подобное:
https://github.com/araisrobo/linuxcnc/b ... s/tp.c#808
- Starik
- Опытный
- Сообщения: 136
- Зарегистрирован: 13 май 2012, 21:22
- Репутация: 17
- Откуда: Долгопрудный
Re: LinuxCNC S-разгон и торможение
Да вроде в ja3 внесли уже... на youtube плазма ездит с этой версией... Там хвосты остались вроде как, типа синхронизацию со шпинделем еще не дописали... А может уже и ее дописали -- вроде как "rigid tapping" работает тоже.Интересно, оно работает? Почему его не вносят в тестовые версии?
-
- Зачётный участник
- Сообщения: 34042
- Зарегистрирован: 04 апр 2010, 19:22
- Репутация: 6192
- Откуда: Казахстан.
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
сцылкуaystarik писал(а): на youtube плазма ездит с этой версией...
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
- PKM
- Почётный участник
- Сообщения: 4263
- Зарегистрирован: 31 мар 2011, 18:11
- Репутация: 705
- Настоящее имя: Андрей
- Откуда: Украина
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
Разве они для рабочих ходов используют S-кривые?aystarik писал(а):синхронизацию со шпинделем еще не дописали... А может уже и ее дописали -- вроде как "rigid tapping" работает тоже
- Starik
- Опытный
- Сообщения: 136
- Зарегистрирован: 13 май 2012, 21:22
- Репутация: 17
- Откуда: Долгопрудный
Re: LinuxCNC S-разгон и торможение
https://www.youtube.com/watch?v=BraEMAu5UkYaftaev писал(а):сцылку
- Starik
- Опытный
- Сообщения: 136
- Зарегистрирован: 13 май 2012, 21:22
- Репутация: 17
- Откуда: Долгопрудный
Re: LinuxCNC S-разгон и торможение
А для чего же их еще использовать????PKM писал(а):Разве они для рабочих ходов используют S-кривые?
-
- Зачётный участник
- Сообщения: 34042
- Зарегистрирован: 04 апр 2010, 19:22
- Репутация: 6192
- Откуда: Казахстан.
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
на вид ничего не обычногоaystarik писал(а):Да вроде в ja3 внесли уже... на youtube плазма ездит с этой версией...
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
- Starik
- Опытный
- Сообщения: 136
- Зарегистрирован: 13 май 2012, 21:22
- Репутация: 17
- Откуда: Долгопрудный
Re: LinuxCNC S-разгон и торможение
в этом и щастьеaftaev писал(а):на вид ничего не обычного
-
- Зачётный участник
- Сообщения: 34042
- Зарегистрирован: 04 апр 2010, 19:22
- Репутация: 6192
- Откуда: Казахстан.
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
Сняли бы видео и так и так чтоб было видна разница
Дилетанту сложные вещи кажутся очень простыми, и только профессионал понимает насколько сложна самая простая вещь
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
Кто хочет - ищет возможности, кто не хочет - ищет оправдание.
Найди работу по душе и тебе не придется работать.
- Starik
- Опытный
- Сообщения: 136
- Зарегистрирован: 13 май 2012, 21:22
- Репутация: 17
- Откуда: Долгопрудный
Re: LinuxCNC S-разгон и торможение
А разве не видно _удивительной_ плавности и легкости перемещений? Прямо ж как лебедь белая плывет...
- PKM
- Почётный участник
- Сообщения: 4263
- Зарегистрирован: 31 мар 2011, 18:11
- Репутация: 705
- Настоящее имя: Андрей
- Откуда: Украина
- Контактная информация:
Re: LinuxCNC S-разгон и торможение
Почти во всех контроллерах только для ускоренных. А для рабочих при невысоких скоростях не особо и нужны.aystarik писал(а):А для чего же их еще использовать????