Программирование LEGO NXT роботов на языке NXC - Еще раз о моторах — различия между версиями

Материал из roboforum.ru Wiki
Перейти к: навигация, поиск
(Еще раз о моторах)
(Подводим итоги)
 
(не показано 8 промежуточных версий этого же участника)
Строка 22: Строка 22:
 
Команды OnFwd() и OnRev() являются простейшими командами для управления моторами.
 
Команды OnFwd() и OnRev() являются простейшими командами для управления моторами.
  
Сервомоторы из набора NXT имеют встроенные энкодеры, которые позволяют вам достаточно точно контролировать положение вала и скорость его вращения. Встроенная в NXT прошивка реализует PID (Proportional Integrative Derivative) closed-loop controller to control motors'
+
Сервомоторы из набора NXT имеют встроенные энкодеры, которые позволяют вам достаточно точно контролировать положение вала и скорость его вращения.
position and speed using encoders as feedback.
 
If you want your robot to go perfectly straight, you can use a synchronization feature that makes the selected
 
couple of motors run together and wait for each other in case one of them is slowed down or even blocked; in a
 
similar way, you can set a couple of motors to run together in sync, with a percentage of steering to turn left,
 
right or spin in place, but always keeping sync. There are many commands to unleash servomotors' full power!
 
OnFwdReg(‘ports',‘speed',‘regmode') drives the motors specified by ‘ports' at the ‘speed' power
 
applying the regulation mode that can be either OUT_REGMODE_IDLE, OUT_REGMODE_SPEED or
 
OUT_REGMODE_SYNC. If IDLE is selected, no PID regulation will be applied; if SPEED mode is selected, the
 
NXT regulates single motor to get a constant speed, even if load on motor varies; finally, if SYNC is selected,
 
the couple of motors specified by ‘ports' move in sync as explained before.
 
OnRevReg() acts as the precedent command, reversing direction.
 
  
task main()
+
Встроенная в NXT прошивка реализует алгоритм ПИД-управления (Пропорциональный Интегральный Дифференциальный - от названия основных трёх его компонент) положением вала и скоростью его вращения с обратной связью через энкодеры.
{
+
 
OnFwdReg(OUT_AC,50,OUT_REGMODE_IDLE);
+
Если вы хотите, чтобы ваш робот ездил строго по прямой, вы можете использовать возможность синхронизации двигателей, которая объединяет их в пару, в которой каждый двигатель замедляется, если второй не успевает крутиться с нужной скоростью. Подобным образом вы можете настроить пару моторов на работу в синхронизированном режиме с процентом скорости левого двигателя по отношению к правом, для поворота направо, налево или вращения на месте, при этом траектория будет выполняться достаточно точно. Существует множество команд, которые позволяют полностью использовать возможности сервомоторов из набора NXT!
Wait(2000);
+
 
Off(OUT_AC);
+
Команда OnFwdReg(‘ports',‘speed',‘regmode') включает двигатели указанные в ‘ports' на движение вперед со скоростью ‘speed' применяя режим регуляции, который может быть OUT_REGMODE_IDLE, OUT_REGMODE_SPEED или OUT_REGMODE_SYNC. Если выбран режим IDLE, ПИД-регулирование будет отключено; если режим SPEED, Модуль NXT будет регулировать скорость отдельных моторов чтобы получить постоянную скорость, даже если нагрузка на мотор меняется; и наконец, если выбран режим SYNC, пара моторов указанная в ‘ports' работают в синхронизированном режиме, как было описано выше.
PlayTone(4000,50);
+
 
Wait(1000);
+
Команда OnRevReg() работает так же как и выше, только в другую сторону.
ResetTachoCount(OUT_AC);
+
 
OnFwdReg(OUT_AC,50,OUT_REGMODE_SPEED);
+
task main()
Wait(2000);
+
{
Off(OUT_AC);
+
  OnFwdReg(OUT_AC,50,OUT_REGMODE_IDLE);
PlayTone(4000,50);
+
  Wait(2000);
Wait(1000);
+
  Off(OUT_AC);
OnFwdReg(OUT_AC,50,OUT_REGMODE_SYNC);
+
  PlayTone(4000,50);
Wait(2000);
+
  Wait(1000);
Off(OUT_AC);
+
  ResetTachoCount(OUT_AC);
}
+
  OnFwdReg(OUT_AC,50,OUT_REGMODE_SPEED);
This program shows well different regulation if you try to stop wheels holding the robot in your hand: first
+
  Wait(2000);
(IDLE mode), stopping a wheel you will not notice anything; then (SPEED MODE), trying to slow down a
+
  Off(OUT_AC);
wheel, you'll see that NXT increases motor's power to overcome your hold, trying to keep speed constant; finally
+
  PlayTone(4000,50);
(SYNC mode), stopping a wheel will cause the other one to stop, waiting for the blocked one.
+
  Wait(1000);
OnFwdSync(‘ports',‘speed',‘turnpct') is the same as OnFwdReg() command in SYNC mode, but
+
  OnFwdReg(OUT_AC,50,OUT_REGMODE_SYNC);
now you can also specify the 'turnpct' steering percentual (from -100 to 100).
+
  Wait(2000);
OnRevSync() is the same as before, simply reversing the motor's direction. The following program shows
+
  Off(OUT_AC);
these commands: try changing steering number to see how it behaves.
+
}
task main()
+
 
{
+
Эта программа показывает различные способы регулирования. Если вы попробуете остановить колёса робота, удерживая их в руках, при первом режиме (IDLE) ничего не будет происходить, во втором режиме (SPEED) попытка замедлить колесо вызовет увеличение мощности подаваемой на этот мотор, так как NXT пытается добиться заданной ему скорости; и наконец, в режиме синхронизации (SYNC), если попытаться остановить одно колесо - второе так же остановится, дожидаясь заблокированного колеса.
PlayTone(5000,30);
+
 
OnFwdSync(OUT_AC,50,0);
+
OnFwdSync(‘ports',‘speed',‘turnpct') делает то же самое что OnFwdReg() в режиме SYNC, но можно указать 'turnpct' - процент поворота влево\вправо (от -100 до 100).
Wait(1000);
+
 
PlayTone(5000,30);
+
OnRevSync() делает то же самое что и предыдущая команда, только направления обратные. Следующая программа показывает эти команды в работе: попробуйте менять процент поворота, чтобы увидеть как это влияет на работу двигателей.
OnFwdSync(OUT_AC,50,20);
+
 
Wait(1000);
+
task main()
PlayTone(5000,30);
+
{
OnFwdSync(OUT_AC,50,-40);
+
  PlayTone(5000,30);
Wait(1000);
+
  OnFwdSync(OUT_AC,50,0);
PlayTone(5000,30);
+
  Wait(1000);
OnRevSync(OUT_AC,50,90);
+
  PlayTone(5000,30);
Wait(1000);
+
  OnFwdSync(OUT_AC,50,20);
Off(OUT_AC);
+
  Wait(1000);
}
+
  PlayTone(5000,30);
Finally, motors can be set to turn by a limited number of degrees (remember that a full turn is 360°).
+
  OnFwdSync(OUT_AC,50,-40);
For both following commands, you can act on motor's direction changing either the sign of the speed or the sign
+
  Wait(1000);
of the angle: so, if speed and angle have the same sign, motor will run forwards, if their sign is opposite, the
+
  PlayTone(5000,30);
motor will run backwards.
+
  OnRevSync(OUT_AC,50,90);
RotateMotor(‘ports',‘speed',‘degrees') rotates the motor shaft specified by ‘ports' by a ‘degrees'
+
  Wait(1000);
angle at ‘speed' power (in 0-100 range).
+
  Off(OUT_AC);
 +
}
 +
 
 +
И наконец, моторы можно поворачивать на конкретное число градусов (помните, что полный оборот это 360°).
 +
 
 +
Для обоих следующих команд, вы можете указывать направление вращения моторов или знаком скорости или знаком угла: так что если скорость или знак имеют один и тот же знак - мотор будет крутиться вперед, иначе назад.
 +
 
 +
RotateMotor(‘ports',‘speed',‘degrees') вращает вал мотора указанного в ‘ports' на ‘degrees' градусов со скоростью ‘speed' (в диапазоне 0-100).
 +
 
 +
task main()
 +
{
 +
  RotateMotor(OUT_AC, 50,360);
 +
  RotateMotor(OUT_C, 50,-360);
 +
}
 +
 
 +
RotateMotorEx(‘ports',‘speed',‘degrees',‘turnpct',‘sync', 'stop') это расширение предыдущей команды, которое позволяет синхронизировать два мотора (например, OUT_AC) указывая процент поворота ‘turnpct' (от -100 до 100) и флаг ‘sync' (который может быть или истиной или ложью). Также команда позволяет указать - нужно ли по её завершении блокировать вал двигателя, для этого используется флаг 'stop'.
 +
 
 +
task main()
 +
{
 +
  RotateMotorEx(OUT_AC, 50, 360, 0, true, true);
 +
  RotateMotorEx(OUT_AC, 50, 360, 40, true, true);
 +
  RotateMotorEx(OUT_AC, 50, 360, -40, true, true);
 +
  RotateMotorEx(OUT_AC, 50, 360, 100, true, true);
 +
}
  
task main()
 
{
 
RotateMotor(OUT_AC, 50,360);
 
RotateMotor(OUT_C, 50,-360);
 
}
 
RotateMotorEx(‘ports',‘speed',‘degrees',‘turnpct',‘sync', 'stop') is an extension of the
 
precedent command, that lets you synchronize two motors (e.g. OUT_AC) specifying a ‘turnpct' steering
 
percentage (from -100 to 100) and a boolean flag ‘sync' (that can be set to true or false). It also lets you
 
specify whether the motors should brake after the angle of rotation has completed using the boolean flag 'stop'.
 
task main()
 
{
 
RotateMotorEx(OUT_AC, 50, 360, 0, true, true);
 
RotateMotorEx(OUT_AC, 50, 360, 40, true, true);
 
RotateMotorEx(OUT_AC, 50, 360, -40, true, true);
 
RotateMotorEx(OUT_AC, 50, 360, 100, true, true);
 
}
 
 
==ПИД-управление==
 
==ПИД-управление==
NXT firmware implements a digital PID (proportional integrative derivative) controller to regulate servomotors'
+
Встроенное программное обеспечение NXT реализует цифровой ПИД-регулятор для точного управления положением и скорости сервомоторов. Этот тип управления один из самых простых и при этом эффективных способов управления с обратной связью, широко используемый во всяких задача автоматизации.
position and speed with precision. This controller type is one of the simplest yet most effective closed loop
+
 
feedback controller known is automation, and is often used.
+
Если кратко, он работает так (Я буду говорить об управлении положением вала цифровым контроллером):
In rough words, it works so (I'll talk about position regulation for a discrete time controller):
+
 
Your program gives the controller a set point R(t) to reach; it actuates the motor with a command U(t) ,
+
Ваша программа задаёт контроллеру требуемое положение R(t); он выдаёт мощность U(t) на двигатель, замеряя положение вала Y(t) встроенными энкодерами и рассчитывает отклонение E(t) = R(t) – Y(t): вот почему это называется контроллер с обратной связью, потому что выходное положение вала мотора возвращается на вход контроллера, чтобы посчитать насколько он сейчас промахивается. Контроллер при этом превращает размер отклонения E(t) в новую команду для двигателя U(t) таким образом:
measuring its position Y(t) with the built-in encoder and calculates an error E(t) = R(t) – Y(t): here's why it is
+
 
called a "closed loop controller", because the output position Y(t) is brought back to the controller's input to
+
U(t) = P(t) + I(t) + D(t), где
calculate the error. The controller transforms the error E(t) into the command U(t) so:
+
 
U(t) = P(t) + I(t) + D(t), where
 
 
P(t) = KP·E(t),
 
P(t) = KP·E(t),
 +
 
I(t) = KI·( I(t–1) + E(t) )
 
I(t) = KI·( I(t–1) + E(t) )
and D(t) = KD·(E(t) – E(t –1)).
 
It could seem quite hard for a novice, but I'll try to explain this mechanism as best as I can.
 
The command is the sum of three contributes, the proportional part P(t), the integrative part I(t) and the
 
derivative part D(t) .
 
P(t) makes the controller quick in time, but it does not assure a null error at equilibrium;
 
I(t) gives “memory” to the controller, in the sense that it takes trace of accumulated errors and compensates
 
them, with the guarantee of a zero error at equilibrium;
 
D(t) gives “future prediction” to the controller (as derivation in math), speeding up response.
 
I know this can still be confusing, consider that entire academic books have been written on this argument! But
 
we can still try it online, with our NXT brick! The simple program to fix things into memory is the following.
 
  
#define P 50
+
и D(t) = KD·(E(t) – E(t –1)).
#define I 50
+
 
#define D 50
+
Это может выглядеть достаточно сложно для новичка, но я предприму все усилия, чтобы помочь вам объяснить этот механизм.
task main(){
+
Команда является суммой трёх частей, Пропорциональной части P(t), интегральной I(t) и дифференциальной D(t).
RotateMotorPID(OUT_A, 100, 180, P, I, D);
+
 
Wait(3000);
+
P(t) даёт контроллеру быстроту реакции, но может мешать стабильности в долгосрочной перспективе;
}
+
 
The RotateMotorPID(port,speed, angle, Pgain,Igain,Dgain) let you move a motor setting different PID gains
+
I(t) даёт контроллеру “память”, в том смысле, что накапливает ошибку и компенсирует её, гарантируя долгосрочную стабилизацию в нужном положении;
from the default ones. Try setting the following values
+
 
(50,0,0): the motor does not rotate 180° exactly, since an uncompensated error remains
+
D(t) даёт контроллеру “возможность предугадывать” (на основе производной из математики), ускоряя время реакции системы.
(0,x,x): without proportional part, the error is very big
+
 
(40,40,0): there's an overshoot, that means the motor shaft moves beyond the set point and then turns back
+
Я понимаю, что это может всё еще казаться запутанным, на самом деле на эту тему написаны целые научные книги! Но мы всё еще можем попробовать это в реальности с нашим NXT! Простая программа, которая поможет зафиксировать в памяти эту тему:
(40,40,90): good precision and raising time (time to reach the set point)
+
 
(40,40,200): the shaft oscillate, since derivative gain is too high
+
#define P 50
Try other values to discover how these gains influence a motor's performance.
+
#define I 50
 +
#define D 50
 +
task main(){
 +
  RotateMotorPID(OUT_A, 100, 180, P, I, D);
 +
  Wait(3000);
 +
}
 +
 
 +
Функция RotateMotorPID(port,speed, angle, Pgain,Igain,Dgain) позволяет управлять мотором устанавливая различные параметры ПИД-регулятора, отличные от настроек по умолчанию. Попробуйте выставлять следующие значения:
 +
 
 +
(50,0,0): мотор не поворачивается точно на 180°, так как остаётся нескомпенсированная ошибка
 +
 
 +
(0,x,x): без пропорциональной части ошибка очень большая
 +
 
 +
(40,40,0): здесь у нас перелёт, т.е. мотор поворачивается дальше чем надо и потом возвращается
 +
 
 +
(40,40,90): хорошая точность и время выполнения команд
 +
 
 +
(40,40,200): вал колеблется, так как дифференциальная часть слишком большая
 +
 
 +
Попробуйте другие значения, чтобы посмотреть как разные настройки ПИД-регулятора влияют на выполнение команд.
  
 
==Подводим итоги==
 
==Подводим итоги==
In this chapter you learned about the advanced motor commands available: Float(),Coast() that stop the
+
В этой главе вы освоили дополнительные команды для управления моторами: Float(),Coast() которые плавно останавливают моторы; OnXxxReg() и OnXxxSync() которые реализуют управление с обратной связью как по скорости, так и по синхронизации со вторым мотором;
motor gently; OnXxxReg(), and OnXxxSync() that allow feedback control on motors' speed and sync;
+
RotateMotor() и RotateMotorEx() используемые для поворота на нужный угол выходного вала моторов. Вы немного изучили что такое ПИД-регулирование; хотя это было не исчерпывающее объяснение, может быть я вас даже немного запутал, попробуйте поискать материал на эту тему в Интернете!
RotateMotor() and RotateMotorEx() are used to turn motor's shaft by a precise number of degrees. You
 
learned something about PID control too; it has not been an exhaustive explanation, but maybe I have caused a
 
bit of curiosity in you: search the web about it!
 

Текущая версия на 12:50, 19 мая 2009

Автор: Daniele Benedettelli

Перевод: © Ботов Антон aka =DeaD=, 2009

Эксклюзивно для www.roboforum.ru
копирование на другие ресурсы и публикация перевода
без разрешения его автора запрещены

Еще раз о моторах

Существует несколько дополнительных команд для моторов, которые вы можете использовать для более точного управления моторами. В этой главе мы обсудим эти команды: ResetTachoCount, Coast (Float), OnFwdReg, OnRevReg, OnFwdSync, OnRevSync, RotateMotor, RotateMotorEx, а также основы ПИД-управления.

Плавная остановка

Когда вы используете команду Off(), сервомотор мгновенно останавливается, блокируя вал и удерживая позицию. Существует способ более мягкой остановки мотора не используя блокировку вала. Для этого используйте команды Float() или что то же самое - Coast(), они просто отключают питание моторов. Вот пример, сначала робот останавливается используя блокировку вала, а потом останавливается без использования блокировки. Обратите внимание на разницу. На самом деле для конкретно этого робота разница достаточно незаметна, но для других роботов эта разница будет гораздо больше.

task main()
{
  OnFwd(OUT_AC, 75);
  Wait(500);
  Off(OUT_AC);
  Wait(1000);
  OnFwd(OUT_AC, 75);
  Wait(500);
  Float(OUT_AC);
}

Дополнительные команды

Команды OnFwd() и OnRev() являются простейшими командами для управления моторами.

Сервомоторы из набора NXT имеют встроенные энкодеры, которые позволяют вам достаточно точно контролировать положение вала и скорость его вращения.

Встроенная в NXT прошивка реализует алгоритм ПИД-управления (Пропорциональный Интегральный Дифференциальный - от названия основных трёх его компонент) положением вала и скоростью его вращения с обратной связью через энкодеры.

Если вы хотите, чтобы ваш робот ездил строго по прямой, вы можете использовать возможность синхронизации двигателей, которая объединяет их в пару, в которой каждый двигатель замедляется, если второй не успевает крутиться с нужной скоростью. Подобным образом вы можете настроить пару моторов на работу в синхронизированном режиме с процентом скорости левого двигателя по отношению к правом, для поворота направо, налево или вращения на месте, при этом траектория будет выполняться достаточно точно. Существует множество команд, которые позволяют полностью использовать возможности сервомоторов из набора NXT!

Команда OnFwdReg(‘ports',‘speed',‘regmode') включает двигатели указанные в ‘ports' на движение вперед со скоростью ‘speed' применяя режим регуляции, который может быть OUT_REGMODE_IDLE, OUT_REGMODE_SPEED или OUT_REGMODE_SYNC. Если выбран режим IDLE, ПИД-регулирование будет отключено; если режим SPEED, Модуль NXT будет регулировать скорость отдельных моторов чтобы получить постоянную скорость, даже если нагрузка на мотор меняется; и наконец, если выбран режим SYNC, пара моторов указанная в ‘ports' работают в синхронизированном режиме, как было описано выше.

Команда OnRevReg() работает так же как и выше, только в другую сторону.

task main()
{
  OnFwdReg(OUT_AC,50,OUT_REGMODE_IDLE);
  Wait(2000);
  Off(OUT_AC);
  PlayTone(4000,50);
  Wait(1000);
  ResetTachoCount(OUT_AC);
  OnFwdReg(OUT_AC,50,OUT_REGMODE_SPEED);
  Wait(2000);
  Off(OUT_AC);
  PlayTone(4000,50);
  Wait(1000);
  OnFwdReg(OUT_AC,50,OUT_REGMODE_SYNC);
  Wait(2000);
  Off(OUT_AC);
}

Эта программа показывает различные способы регулирования. Если вы попробуете остановить колёса робота, удерживая их в руках, при первом режиме (IDLE) ничего не будет происходить, во втором режиме (SPEED) попытка замедлить колесо вызовет увеличение мощности подаваемой на этот мотор, так как NXT пытается добиться заданной ему скорости; и наконец, в режиме синхронизации (SYNC), если попытаться остановить одно колесо - второе так же остановится, дожидаясь заблокированного колеса.

OnFwdSync(‘ports',‘speed',‘turnpct') делает то же самое что OnFwdReg() в режиме SYNC, но можно указать 'turnpct' - процент поворота влево\вправо (от -100 до 100).

OnRevSync() делает то же самое что и предыдущая команда, только направления обратные. Следующая программа показывает эти команды в работе: попробуйте менять процент поворота, чтобы увидеть как это влияет на работу двигателей.

task main()
{
  PlayTone(5000,30);
  OnFwdSync(OUT_AC,50,0);
  Wait(1000);
  PlayTone(5000,30);
  OnFwdSync(OUT_AC,50,20);
  Wait(1000);
  PlayTone(5000,30);
  OnFwdSync(OUT_AC,50,-40);
  Wait(1000);
  PlayTone(5000,30);
  OnRevSync(OUT_AC,50,90);
  Wait(1000);
  Off(OUT_AC);
}

И наконец, моторы можно поворачивать на конкретное число градусов (помните, что полный оборот это 360°).

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

RotateMotor(‘ports',‘speed',‘degrees') вращает вал мотора указанного в ‘ports' на ‘degrees' градусов со скоростью ‘speed' (в диапазоне 0-100).

task main()
{
  RotateMotor(OUT_AC, 50,360);
  RotateMotor(OUT_C, 50,-360);
}

RotateMotorEx(‘ports',‘speed',‘degrees',‘turnpct',‘sync', 'stop') это расширение предыдущей команды, которое позволяет синхронизировать два мотора (например, OUT_AC) указывая процент поворота ‘turnpct' (от -100 до 100) и флаг ‘sync' (который может быть или истиной или ложью). Также команда позволяет указать - нужно ли по её завершении блокировать вал двигателя, для этого используется флаг 'stop'.

task main()
{
  RotateMotorEx(OUT_AC, 50, 360, 0, true, true);
  RotateMotorEx(OUT_AC, 50, 360, 40, true, true);
  RotateMotorEx(OUT_AC, 50, 360, -40, true, true);
  RotateMotorEx(OUT_AC, 50, 360, 100, true, true);
}

ПИД-управление

Встроенное программное обеспечение NXT реализует цифровой ПИД-регулятор для точного управления положением и скорости сервомоторов. Этот тип управления один из самых простых и при этом эффективных способов управления с обратной связью, широко используемый во всяких задача автоматизации.

Если кратко, он работает так (Я буду говорить об управлении положением вала цифровым контроллером):

Ваша программа задаёт контроллеру требуемое положение R(t); он выдаёт мощность U(t) на двигатель, замеряя положение вала Y(t) встроенными энкодерами и рассчитывает отклонение E(t) = R(t) – Y(t): вот почему это называется контроллер с обратной связью, потому что выходное положение вала мотора возвращается на вход контроллера, чтобы посчитать насколько он сейчас промахивается. Контроллер при этом превращает размер отклонения E(t) в новую команду для двигателя U(t) таким образом:

U(t) = P(t) + I(t) + D(t), где

P(t) = KP·E(t),

I(t) = KI·( I(t–1) + E(t) )

и D(t) = KD·(E(t) – E(t –1)).

Это может выглядеть достаточно сложно для новичка, но я предприму все усилия, чтобы помочь вам объяснить этот механизм. Команда является суммой трёх частей, Пропорциональной части P(t), интегральной I(t) и дифференциальной D(t).

P(t) даёт контроллеру быстроту реакции, но может мешать стабильности в долгосрочной перспективе;

I(t) даёт контроллеру “память”, в том смысле, что накапливает ошибку и компенсирует её, гарантируя долгосрочную стабилизацию в нужном положении;

D(t) даёт контроллеру “возможность предугадывать” (на основе производной из математики), ускоряя время реакции системы.

Я понимаю, что это может всё еще казаться запутанным, на самом деле на эту тему написаны целые научные книги! Но мы всё еще можем попробовать это в реальности с нашим NXT! Простая программа, которая поможет зафиксировать в памяти эту тему:

#define P 50
#define I 50
#define D 50
task main(){
  RotateMotorPID(OUT_A, 100, 180, P, I, D);
  Wait(3000);
}

Функция RotateMotorPID(port,speed, angle, Pgain,Igain,Dgain) позволяет управлять мотором устанавливая различные параметры ПИД-регулятора, отличные от настроек по умолчанию. Попробуйте выставлять следующие значения:

(50,0,0): мотор не поворачивается точно на 180°, так как остаётся нескомпенсированная ошибка

(0,x,x): без пропорциональной части ошибка очень большая

(40,40,0): здесь у нас перелёт, т.е. мотор поворачивается дальше чем надо и потом возвращается

(40,40,90): хорошая точность и время выполнения команд

(40,40,200): вал колеблется, так как дифференциальная часть слишком большая

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

Подводим итоги

В этой главе вы освоили дополнительные команды для управления моторами: Float(),Coast() которые плавно останавливают моторы; OnXxxReg() и OnXxxSync() которые реализуют управление с обратной связью как по скорости, так и по синхронизации со вторым мотором; RotateMotor() и RotateMotorEx() используемые для поворота на нужный угол выходного вала моторов. Вы немного изучили что такое ПИД-регулирование; хотя это было не исчерпывающее объяснение, может быть я вас даже немного запутал, попробуйте поискать материал на эту тему в Интернете!