При программировании Lego-роботов иногда необходимо проверить на сколько повернулся мотор. Например, чтобы определить не застрял ли он. |
На самом деле, чаще всего, все ограничится использованием двух из них:
MotorRotationCount
- позволяет получить текущее значение с датчика вращения соответствующего мотора.ResetRotationCount
- сбрасывает текущее значение датчика вращения соответствующего мотора в 0.
sub MoveHeadBack()
{
OnRev(HEAD, HEAD_SPEED_REV);
int Start;
do {
Start = MotorRotationCount(HEAD);
Wait(100);
} while (abs(MotorRotationCount(HEAD) - Start) > 5)
Coast(HEAD);
Wait(200);
ResetRotationCount(HEAD);
Wait(1);
}
Эта функция предназначена для того, чтобы сдвинуть выбрасывающий механизм робота для игры в крестики-нолики назад.Поскольку до запуска этой подпрограммы неизвестно, где находися механизм, он должен двигаться наза до тех пор пока не упрется в соответствующие ограничители движения.
Именно это происходит в цикле - через каждые 100 милисекунд проверяется на сколько повернулась ось двигателя со времени последнего измерения, и если поворот произошел меньше чем на 5 градусов, то значит выбрасывающий механизм уперся в ограничитель, и его нужно останавливать.
В конце функции происходит сброс счетчика поворотов мотора (просто для примера, на самом деле он здесь не обязателен).
Заметьте, что после сброса стоит пауза в 1 милисекунду, наличие которой может вызвать обоснованные вопросы.
Дело в том, что подобно функциям
OnFwd()
и OnRev()
, сброс счетчика имеет асинхронную природу. Функция не дожидается реального сброса показаний сенсора, а просто модифицирует нужную область памяти, подразумевая, что модуль Output, запущенный виртуальной машиной блока NXT, обработает изменение памяти соответствующим образом, что приведет к реальному сбросу счетчиков.Так вот, по своей природе, виртуальная машина NXT блока позволяет запускаться всем модулям не чаще, чем один раз в 1 мс. И если
ResetRotationCount()
вызывается в самом конце милисекундного интервала, то Output модуль вызовется практически сразу же после этой функции, что приведет почти к мгновенному сбросу счетчиков. А если ResetRotationCount()
вызывается в начале этого интервала, то последующий вызов, например, MotorRotationCount()
будет показывать старые значения и будет казаться, что ResetRotationCount()
как будто бы не работает (англоязычное объяснение, описанного выше, можно найти на багртрекере BricxCC).Те, кто привык все понимать через анализ рабочего кода, могут рассмотреть два примера:
- Внешне выглядит, что показания счетчика не сбрасываются
OnRev(OUT_A, 50); Wait(1000); TextOut(0, LCD_LINE1, MotorRotationCount(OUT_A)); ResetRotationCount(OUT_A); TextOut(0, LCD_LINE2, MotorRotationCount(OUT_A));
- Добавление паузы решает проблему
OnRev(OUT_A, 50); Wait(1000); TextOut(0, LCD_LINE1, MotorRotationCount(OUT_A)); ResetRotationCount(OUT_A); Wait(1); TextOut(0, LCD_LINE2, MotorRotationCount(OUT_A));
Комментариев нет:
Отправить комментарий