jenya7 0 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба Когда было два мотора я по энкодерам брал их позицию, сравнивал, и если была разница в позициях больше пороговой - один мотор замедлял, другой ускорял. uint32_t MOT_GetPosDif(uint32_t pos1, uint32_t pos2, uint32_t *gt) { if( pos1 > pos2) { *gt = 0; return (pos1 - pos2); } else { *gt = 1; return (pos2 - pos1); } } void MOT_PositionLoopDouble(void) { uint32_t position1, position2, posdif, gt; uint32_t pwm1, pwm2; position1 = motor1_data_double->position; position2 = motor2_data_double->position; posdif = MOT_GetPosDif(position1, position2, >); if (posdif > glob_mot_data.max_pos_diff) { //retry glob_mot_data.pos_diff_count++; if (glob_mot_data.pos_diff_count > glob_mot_data.max_pos_diff_count) { //maximum retries - unable to adjust speed glob_mot_data.pos_diff_count = 0; //send stop command MOT_SendData(motor1_data_double, CAN_COM_STOP, 0); MOT_SendData(motor2_data_double, CAN_COM_STOP, 0); sys_status |= MOT_POS_DIFF; } } else glob_mot_data.pos_diff_count = 0; //no position difference - maximum speed if (posdif < glob_mot_data.max_pos_diff) { MOT_SendData(motor1_data_double, CAN_COM_SSET, glob_mot_data.pwm_max); MOT_SendData(motor2_data_double, CAN_COM_SSET, glob_mot_data.pwm_max); } else { pwm1 = motor1_data_double->speed; pwm2 = motor2_data_double->speed; if (gt == 0) //position1 > position2 -> motor1 runs faster { //adjust pwm pwm1 -= glob_mot_data.pwm_delta; //motor1 speed down pwm2 += glob_mot_data.pwm_delta; //motor2 speed up //check min pwm limit if (pwm1 < glob_mot_data.pwm_min) pwm1 = glob_mot_data.pwm_min; //check max pwm limit if (pwm2 > glob_mot_data.pwm_max) pwm2 = glob_mot_data.pwm_max; } else if (gt == 1) //position2 > position1 -> motor2 runs faster { //adjust pwm pwm1 += glob_mot_data.pwm_delta; //motor1 speed up pwm2 -= glob_mot_data.pwm_delta; //motor2 speed down //check max pwm limit if (pwm1 > glob_mot_data.pwm_max) pwm1 = glob_mot_data.pwm_max; //check min pwm limit if (pwm2 < glob_mot_data.pwm_min) pwm2 = glob_mot_data.pwm_min; } } //update speed MOT_SendData(motor1_data_double, CAN_COM_SSET, pwm1); MOT_SendData(motor2_data_double, CAN_COM_SSET, pwm2); } Теперь моторов 4 и алгоритмика намного усложнилась, Не соображу как отследить разницу в позициях нескольких моторов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба Теперь моторов 4 и алгоритмика намного усложнилась, Не соображу как отследить разницу в позициях нескольких моторов. Привязаться к самому медленному или к самому быстрому. Т.е. в начале каждого цикла определять крайнего и к нему привязываться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба Привязаться к самому медленному или к самому быстрому. Т.е. в начале каждого цикла определять крайнего и к нему привязываться. тогда уж относительно среднего значения выравнивать все остальные. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба тогда уж относительно среднего значения выравнивать все остальные. А где гарантии, что ваше управление при этом будет стабильным? У вас и так нет интегральной составляющей, т.е. ваш алгоритм в пределе не стремится к нулевой ошибке. Это значит что он в принципе-то осциллирующий даже с двумя моторами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба А где гарантии, что ваше управление при этом будет стабильным? У вас и так нет интегральной составляющей, т.е. ваш алгоритм в пределе не стремится к нулевой ошибке. Это значит что он в принципе-то осциллирующий даже с двумя моторами. с двумя моторами работает на удивление хорошо. пробовали вносить разные перекосы, позиция выравниватся быстро и четко. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба с двумя моторами работает на удивление хорошо. пробовали вносить разные перекосы, позиция выравниватся быстро и четко. Так нестабильные законы управления не проявляются на скачках, они проявляются на более сложных функциях возмущений. Поэтому при встрече с настоящим прерывистым кулоновским трением могут быть сюрпризы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба Так нестабильные законы управления не проявляются на скачках, они проявляются на более сложных функциях возмущений. Поэтому при встрече с настоящим прерывистым кулоновским трением могут быть сюрпризы. знаете, мне бы с алгоритмом разобраться, а с кулоновским трением уже потом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба знаете, мне бы с алгоритмом разобраться, а с кулоновским трением уже потом. Взятие за основу среднего создаст положительную обратную связь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба А что скажут алгоритмисты на такое решение? uint32_t MOT_GetMedianPosition(void) { int i; uint32_t position=0; for (i = 0; i < g_linked_motors; i++) { position += linked_motor_data[i]->position; } position /= g_linked_motors; return position; } uint32_t ProcessMedianPosition(void) { int i; uint32_t pos_diff=0; uint32_t median_position = MOT_GetMedianPosition(); for (i = 0; i < g_linked_motors; i++) { if ( abs(linked_motor_data[i]->position - median_position) > glob_mot_data.max_pos_diff) { pos_diff = 1; if (linked_motor_data[i]->position > median_position) //motor runs faster { //adjust speed -> speed down linked_motor_data[i]->pwm -= glob_mot_data.pwm_delta; //check limit if (linked_motor_data[i]->pwm < glob_mot_data.pwm_min) linked_motor_data[i]->pwm = glob_mot_data.pwm_min; } else //motor runs slower { //adjust speed -> speed up linked_motor_data[i]->pwm += glob_mot_data.pwm_delta; //check limit if (linked_motor_data[i]->pwm > glob_mot_data.pwm_max) linked_motor_data[i]->pwm = glob_mot_data.pwm_max; } } } return pos_diff; } void MOT_PositionLoopMulti(void) { int i; if (ProcessMedianPosition()) { //retry glob_mot_data.pos_diff_count++; //maximum retries - unable to adjust speed if (glob_mot_data.pos_diff_count > glob_mot_data.max_pos_diff_count) { glob_mot_data.pos_diff_count = 0; //send stop command for (i = 0; i < g_linked_motors; i++) MOT_SendData(linked_motor_data[i], CAN_COM_STOP, 0); } else { //update speed for (i = 0; i < g_linked_motors; i++) MOT_SendData(linked_motor_data[i], CAN_COM_SSET, linked_motor_data[i]->pwm); } } else { glob_mot_data.pos_diff_count = 0; //set maximum speed for (i = 0; i < g_linked_motors; i++) MOT_SendData(linked_motor_data[i], CAN_COM_SSET, glob_mot_data.pwm_max); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба А что скажут алгоритмисты на такое решение? В полотенцах разбираться лень. Почитайте теорию: https://ru.wikipedia.org/wiki/ПИД-регулятор Разница между скоростями ваших движков - это сигнал ошибки собственно. У него есть три составляющие согласно той ссылке. У вас и так нет интегральной составляющей, т.е. ваш алгоритм в пределе не стремится к нулевой ошибке. Здесь уважаемый AlexandrY говорит я думаю об интегральной составляющей из приведённой мной выше ссылки. Это второе слагаемое в первой формуле с той ссылки. На той же страничке есть график, показывающий что будет при неучёте каких-то составляющих. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба В полотенцах разбираться лень. Почитайте теорию: https://ru.wikipedia.org/wiki/ПИД-регулятор При описании PID регуляторов почему-то всегда забыват сказать одну важную вещь, которая все ставит на свои места. А именно этот регулятор применим только к нагрузкам тоже являющимся как и PID системами второго порядка. Если система меньшего порядка, то у PID выкидыват какой-либо член, если система большего порядка, то PID-а недостаточно. Порядок в систему может добавить и управляющий сигнал отличающийся от скачка и хитрый сигнал возмущения отличный от шума. В данном случае мы видим применение простейшего пропорционального квантованного управления. Это худший из возможных регуляторов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 6 февраля, 2018 Опубликовано 6 февраля, 2018 · Жалоба В данном случае мы видим применение простейшего пропорционального квантованного управления. Значит: если Jenya7 изучит теорию ПИД, то он уже поднимется как минимум на 2 порядка выше квантового уровня. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 12 февраля, 2018 Опубликовано 12 февраля, 2018 · Жалоба Теперь моторов 4 и алгоритмика намного усложнилась, Не соображу как отследить разницу в позициях нескольких моторов. У меня в похожей задаче в качестве базы задавался всегда наиболее медленный мотор, потому что ускорить его невозможно (заполнение ШИМ 100%). Так что алгоритм и был построен на поиске наиболее медленного мотора(максимальном удалении от цели). ШИМ быстрых моторов определялся эмпирической формулой пропорционально рассогласованию. При ускорении/торможении всех моторов максимум ШИМ (значение ШИМ наиболее медленного мотора ) изменялось линейно. Что касается ПИД ... Не очень хорошо он работает в этих системах, т.к. разрешение датчиков Холла как правило недостаточное, а требования к синхронности - высокие. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 12 февраля, 2018 Опубликовано 12 февраля, 2018 · Жалоба Что касается ПИД ... Не очень хорошо он работает в этих системах, т.к. разрешение датчиков Холла как правило недостаточное, а требования к синхронности - высокие. У датчиков Холла нет разрешения. Оно есть у системы построенной на них. В моей схеме датчики Холла дают разрешение ~1 градус (механический). В системе ТС разрешение может быть ещё выше. И это только разрешение по импульсам самих датчиков. Система построенная на них, при более-менее равномерном вращении, может дать угловое разрешение во много раз выше. PS: Я имею в виду цифровые датчики Холла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 12 февраля, 2018 Опубликовано 12 февраля, 2018 · Жалоба В моей схеме датчики Холла дают разрешение ~1 градус (механический). Мало о чем говорит - слишком много разных моторов существует. Есть датчики на первичном валу, есть на вторичном, со своими достоинствами и недостатками. Надеюсь, топикстартер решит проблему, для этого советую выводить диагностическую информацию в консоль, т.к. просто отладка работает слишком медленно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться