Перейти к содержанию
    

Отследить разницу в позициях моторов.

Когда было два мотора я по энкодерам брал их позицию, сравнивал, и если была разница в позициях больше пороговой - один мотор замедлял, другой ускорял.

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, &gt);
    
    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 и алгоритмика намного усложнилась, Не соображу как отследить разницу в позициях нескольких моторов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Теперь моторов 4 и алгоритмика намного усложнилась, Не соображу как отследить разницу в позициях нескольких моторов.

Привязаться к самому медленному или к самому быстрому.

Т.е. в начале каждого цикла определять крайнего и к нему привязываться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Привязаться к самому медленному или к самому быстрому.

Т.е. в начале каждого цикла определять крайнего и к нему привязываться.

тогда уж относительно среднего значения выравнивать все остальные.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

тогда уж относительно среднего значения выравнивать все остальные.

А где гарантии, что ваше управление при этом будет стабильным?

У вас и так нет интегральной составляющей, т.е. ваш алгоритм в пределе не стремится к нулевой ошибке.

Это значит что он в принципе-то осциллирующий даже с двумя моторами.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А где гарантии, что ваше управление при этом будет стабильным?

У вас и так нет интегральной составляющей, т.е. ваш алгоритм в пределе не стремится к нулевой ошибке.

Это значит что он в принципе-то осциллирующий даже с двумя моторами.

с двумя моторами работает на удивление хорошо. пробовали вносить разные перекосы, позиция выравниватся быстро и четко.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

с двумя моторами работает на удивление хорошо. пробовали вносить разные перекосы, позиция выравниватся быстро и четко.

Так нестабильные законы управления не проявляются на скачках, они проявляются на более сложных функциях возмущений.

Поэтому при встрече с настоящим прерывистым кулоновским трением могут быть сюрпризы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так нестабильные законы управления не проявляются на скачках, они проявляются на более сложных функциях возмущений.

Поэтому при встрече с настоящим прерывистым кулоновским трением могут быть сюрпризы.

знаете, мне бы с алгоритмом разобраться, а с кулоновским трением уже потом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

знаете, мне бы с алгоритмом разобраться, а с кулоновским трением уже потом.

Взятие за основу среднего создаст положительную обратную связь.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что скажут алгоритмисты на такое решение?

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);
    }   
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что скажут алгоритмисты на такое решение?

В полотенцах разбираться лень. Почитайте теорию: https://ru.wikipedia.org/wiki/ПИД-регулятор

Разница между скоростями ваших движков - это сигнал ошибки собственно. У него есть три составляющие согласно той ссылке.

 

У вас и так нет интегральной составляющей, т.е. ваш алгоритм в пределе не стремится к нулевой ошибке.

Здесь уважаемый AlexandrY говорит я думаю об интегральной составляющей из приведённой мной выше ссылки. Это второе слагаемое в первой формуле с той ссылки.

На той же страничке есть график, показывающий что будет при неучёте каких-то составляющих.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В полотенцах разбираться лень. Почитайте теорию: https://ru.wikipedia.org/wiki/ПИД-регулятор

При описании PID регуляторов почему-то всегда забыват сказать одну важную вещь, которая все ставит на свои места.

А именно этот регулятор применим только к нагрузкам тоже являющимся как и PID системами второго порядка.

Если система меньшего порядка, то у PID выкидыват какой-либо член, если система большего порядка, то PID-а недостаточно.

Порядок в систему может добавить и управляющий сигнал отличающийся от скачка и хитрый сигнал возмущения отличный от шума.

 

В данном случае мы видим применение простейшего пропорционального квантованного управления.

Это худший из возможных регуляторов.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В данном случае мы видим применение простейшего пропорционального квантованного управления.

Значит: если Jenya7 изучит теорию ПИД, то он уже поднимется как минимум на 2 порядка выше квантового уровня. :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Теперь моторов 4 и алгоритмика намного усложнилась, Не соображу как отследить разницу в позициях нескольких моторов.

У меня в похожей задаче в качестве базы задавался всегда наиболее медленный мотор, потому что ускорить его невозможно (заполнение ШИМ 100%).

Так что алгоритм и был построен на поиске наиболее медленного мотора(максимальном удалении от цели). ШИМ быстрых моторов определялся эмпирической формулой пропорционально рассогласованию. При ускорении/торможении всех моторов максимум ШИМ (значение ШИМ наиболее медленного мотора ) изменялось линейно.

 

Что касается ПИД ... Не очень хорошо он работает в этих системах, т.к. разрешение датчиков Холла как правило недостаточное, а требования к синхронности - высокие.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что касается ПИД ... Не очень хорошо он работает в этих системах, т.к. разрешение датчиков Холла как правило недостаточное, а требования к синхронности - высокие.

У датчиков Холла нет разрешения. Оно есть у системы построенной на них.

В моей схеме датчики Холла дают разрешение ~1 градус (механический). В системе ТС разрешение может быть ещё выше.

И это только разрешение по импульсам самих датчиков. Система построенная на них, при более-менее равномерном вращении, может дать угловое разрешение во много раз выше.

PS: Я имею в виду цифровые датчики Холла.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В моей схеме датчики Холла дают разрешение ~1 градус (механический).

Мало о чем говорит - слишком много разных моторов существует.

Есть датчики на первичном валу, есть на вторичном, со своими достоинствами и недостатками.

Надеюсь, топикстартер решит проблему, для этого советую выводить диагностическую информацию в консоль, т.к. просто отладка работает слишком медленно.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...