Skip to content

aztechell/matrix_r4_experiments

Repository files navigation

Matrix R4 Experiments

Содержание

Глава 1. Общая информация и ссылки

Этот репозиторий будет хранить эксперименты с контроллером MATRIX R4 / Mini R4: движение по энкодерам, повороты, работа с IMU, движение по линии и тесты датчиков.

Контроллер

MATRIX R4 / Mini R4 — робототехнический контроллер MATRIX Robotics на базе Arduino UNO R4 WiFi. Он программируется из Arduino IDE обычными .ino sketch-файлами через библиотеку MatrixMiniR4.

MATRIX Mini R4 Controller

Изображение: MATRIX Robotics, страница MATRIX Mini R4 Controller Set.

Кратко по возможностям контроллера:

  • 4 порта DC-моторов с поддержкой энкодеров: M1, M2, M3, M4;
  • 4 RC-servo выхода: RC1, RC2, RC3, RC4;
  • встроенный 6-осевой IMU/гиро;
  • встроенный OLED-дисплей 128x32;
  • 2 кнопки: BTN_UP, BTN_DOWN;
  • Wi-Fi и Bluetooth за счет базы Arduino UNO R4 WiFi;
  • 3 аналоговых порта: A1, A2, A3;
  • 4 I2C-порта плюс I2C0 на A3;
  • мониторинг напряжения питания через MiniR4.PWR.

Полезные ссылки

Глава 2. Архитектура платы

MATRIX Mini R4 устроен как двухпроцессорный контроллер. Верхний уровень — это Arduino UNO R4 WiFi, который выполняет пользовательский sketch, работает с Arduino API, Wi-Fi/Bluetooth и частью внешних портов. Нижний уровень — STM32F103, который используется как сопроцессор для задач реального времени: моторы, энкодеры, сервоприводы, IMU и служебные данные питания.

Официальную электрическую схему платы не нашел в открытых ресурсах. Ниже логическая схема по официальному описанию MATRIX и структуре библиотеки MatrixMiniR4.

flowchart TB
    sketch["Arduino sketch (.ino)"] --> api["MatrixMiniR4 API"]
    api --> r4["Arduino UNO R4 WiFi core"]

    r4 --> wireless["Wi-Fi / Bluetooth"]
    r4 --> usb["USB-C upload / Serial"]
    r4 --> i2c0["Wire / I2C0 on A3"]
    r4 --> i2c1["Wire1"]
    r4 <--> lower["STM32F103 lower MCU"]

    i2c0 --> ms018["MS-018 Line Tracer 10CH"]
    i2c1 --> oled["OLED 128x32, address 0x3D"]
    i2c1 --> exti2c["I2C1-I2C4 external ports"]

    lower --> motorPorts["M1-M4 motor ports"]
    lower --> encoders["Encoder feedback"]
    lower --> servos["RC1-RC4 servo outputs"]
    lower --> imu["Built-in 6-axis IMU"]
    lower --> buttons["BTN_UP / BTN_DOWN"]
    lower --> power["Battery voltage monitor"]
Loading

Верхний уровень: Arduino UNO R4 WiFi

На этом уровне выполняется пользовательский код. Когда sketch вызывает MiniR4.begin(), библиотека инициализирует объект MiniR4, OLED, порты, связь с нижним контроллером и встроенные модули.

Этот уровень отвечает за:

  • выполнение .ino программы;
  • работу с USB-C загрузкой и Serial;
  • Wi-Fi/Bluetooth возможности Arduino UNO R4 WiFi;
  • OLED 128x32 через Wire1;
  • внешние I2C-устройства через I2C0/I2C1-I2C4;
  • analog/digital порты, которые проброшены на Arduino-сторону.

Нижний уровень: STM32F103

STM32F103 работает как отдельный контроллер реального времени. В библиотеке он доступен через внутренний слой MMLower: пользователь обычно не вызывает его напрямую, а работает через удобные классы MiniR4.M1, MiniR4.M2, MiniR4.Motion, MiniR4.PWR и так далее.

Через этот нижний уровень идут:

  • команды скорости/мощности DC-моторов;
  • чтение энкодеров;
  • торможение моторов;
  • управление RC-servo;
  • чтение кнопок;
  • чтение IMU;
  • чтение напряжения питания.

В локальном коде библиотеки связь с нижним контроллером создается как MMLower mmL(8, 9, 57600), то есть через внутренний serial-протокол библиотеки.

Почему это важно для кода движения

Вызов вида:

MiniR4.M1.setSpeed(30);

не управляет PWM напрямую с Arduino-процессора. Он отправляет команду в нижний STM32, а тот уже управляет моторным портом. Поэтому поведение setSpeed(), setPower(), тормоза и энкодеров зависит не только от sketch, но и от прошивки нижнего контроллера.

Глава 3. Тесты моторов

В наших тестах используются энкодерные TT-моторы MATRIX, подключенные к портам M1 и M2. Для документации важны две разные вещи: паспортные параметры мотора и реальные измерения на конкретном роботе. Паспорт дает ориентир, но код движения нужно настраивать по реальной скорости колес, потому что батарея, вес, трение, покрытие и колеса меняют результат.

Официальные параметры

Официальная страница MATRIX TT Encoder Motor with metal gear box указывает модель METT-MG001 и такие свойства:

  • металлический редуктор и два выходных вала;
  • встроенный энкодер с A/B-фазами;
  • измерение скорости, угла и направления вращения;
  • поддержка точного движения на расстояние, регулирования скорости и синхронизации моторов;
  • разъем PH2.0-6P.

Для обычной версии MATRIX TT Motor with metal gear box MATRIX указывает скорость редуктора около 130 rpm при 4.5V. На странице энкодерной версии эта цифра в текстовом описании не продублирована, поэтому для METT-MG001 используем ее только как ориентир по семейству TT-моторов, а не как точный предел для нашего робота.

Как проводился тест

Тестовый sketch подавал на левый и правый мотор одинаковую команду от 0 до 100 с шагом 5, считывал энкодеры и считал скорость вращения колес. Питание во время теста было примерно 8.04V в начале и 7.91V в конце.

Исходные данные:

Графики строятся скриптом plot_motor_speed.py.

3.1 Как получены графики

Для графиков используются два файла:

  • MatrixMotorSpeedGraphTest/MatrixMotorSpeedGraphTest.ino — sketch на роботе;
  • plot_motor_speed.py — Python-скрипт на компьютере.

MatrixMotorSpeedGraphTest прогоняет моторы M1 и M2 по командам от 0 до 100 с шагом 5. Для каждой точки он:

  1. задает одинаковую скорость левому и правому мотору;
  2. ждет стабилизацию;
  3. сбрасывает энкодеры;
  4. измеряет, сколько градусов колеса прошли за фиксированное время;
  5. печатает строку CSV в Serial.

Формат Serial-вывода:

power,left_deg_s,right_deg_s,avg_deg_s,battery_v

plot_motor_speed.py читает эти строки с COM-порта или берет уже сохраненный CSV. Потом он:

  • сохраняет расширенный CSV в data/motor_speed_data_mm.csv;
  • пересчитывает deg/s в mm/s через диаметр колеса 65 mm;
  • пересчитывает deg/s в rpm по формуле rpm = deg/s / 6;
  • строит три PNG-графика в assets/.

Запуск с живого робота:

python plot_motor_speed.py --port COM8

Запуск по уже сохраненным данным:

python plot_motor_speed.py --input-csv data\motor_speed_data.csv

Зависимости Python:

python -m pip install -r requirements.txt

Для запуска по готовому CSV нужен только matplotlib; pyserial нужен для чтения данных с COM-порта.

Перед измерением нужно загрузить MatrixMotorSpeedGraphTest, открыть порт только в одном месте и нажать кнопку на роботе. Arduino Serial Monitor при этом должен быть закрыт, иначе Python не сможет открыть COM-порт.

Команда мотора и угловая скорость

Motor command to wheel angular speed

deg/s удобен для энкодеров: это прямая скорость вращения оси колеса. Пересчет в обороты простой:

rpm = deg/s / 6

Например, 1025.7 deg/s при команде 100 — это примерно 171 rpm.

Команда мотора и скорость робота

Motor command to robot speed

mm/s полезнее для движения по расстоянию. Пересчет сделан для диаметра колеса 65 mm:

mm/s = deg/s * pi * 65 / 360

По нашим данным команда 100 дает около 582 mm/s на холостом тесте. На полу под нагрузкой реальная скорость будет ниже.

Команда мотора и RPM

Motor command to wheel rpm

Короткая сводка по точкам:

Команда Среднее, deg/s Среднее, rpm Среднее, mm/s
50 513.0 85.5 291.0
80 822.3 137.1 466.4
100 1025.7 171.0 581.8

Вывод для кода движения

Команда setSpeed(100) — это не гарантированные 100% физической скорости и не паспортная скорость мотора. Это верхняя команда контроллера. Для нашего робота при 2S батарее и колесах 65 mm практический потолок на холостом тесте получился около 170 rpm или 580 mm/s.

Поэтому в движении лучше задавать целевую скорость в mm/s, а внутри кода переводить ее в команду мотора по измеренной таблице. Если робот едет по полу, таблицу нужно уточнить уже под нагрузкой.

Глава 4. Библиотека

Основная библиотека для платы — MatrixMiniR4. В sketch она подключается так:

#include <MatrixMiniR4.h>

Почти вся работа идет через глобальный объект MiniR4. Минимальный старт:

void setup() {
  MiniR4.begin();
}

Шпаргалка по объектам

Объект Что делает Частые методы
MiniR4.M1 ... MiniR4.M4 DC-моторы с энкодерами setSpeed(), setPower(), getDegrees(), resetCounter(), setBrake()
MiniR4.DriveDC готовое управление парой моторов begin(), Move(), MoveSync(), MoveGyro(), TurnGyro(), brake()
MiniR4.RC1 ... MiniR4.RC4 RC-servo выходы setAngle()
MiniR4.Motion встроенный IMU/гиро getGyro(), getAccel(), getEuler(), resetIMUValues()
MiniR4.PWR питание и батарея setBattCell(), getBattVoltage(), getBattPercentage()
MiniR4.OLED OLED 128x32 clearDisplay(), setCursor(), print(), display()
MiniR4.BTN_UP, MiniR4.BTN_DOWN две кнопки на плате getState()
MiniR4.LED встроенные RGB-светодиоды setColor(), setBrightness()
MiniR4.Buzzer встроенный buzzer Tone(), NoTone()
MiniR4.D1 ... MiniR4.D4 digital/PWM порты getL(), getR(), setL(), setR(), setPWML(), setPWMR()
MiniR4.A1 ... MiniR4.A3 analog порты getAIL(), getAIR()
MiniR4.I2C0 ... MiniR4.I2C4 I2C-порты используются для MATRIX I2C-датчиков
MiniR4.Uart / Serial1 UART-порт обычный Arduino UART
MiniR4.WiFi Wi-Fi через UNO R4 WiFi API совместим с WiFiS3

Моторы

setSpeed() — регулируемая скорость через нижний STM32. Это не физические mm/s, а команда от -100 до 100, которую контроллер пытается удерживать по энкодеру.

MiniR4.M1.setSpeed(30);
MiniR4.M2.setSpeed(30);

setPower() — более прямое управление мощностью/PWM без удержания скорости:

MiniR4.M1.setPower(30);
MiniR4.M2.setPower(30);

Энкодеры:

MiniR4.M1.resetCounter();
long deg = MiniR4.M1.getDegrees();

DriveDC

DriveDC — встроенный высокоуровневый слой для двухмоторной базы. Он умеет движение двумя моторами, синхронизацию, движение по гиро и поворот по гиро.

MiniR4.DriveDC.begin(1, 2, true, false);
MiniR4.DriveDC.MoveSync(30, 30);
MiniR4.DriveDC.brake(true);

В библиотеке есть PID-настройки:

MiniR4.DriveDC.setMoveSyncPID(kp, ki, kd);
MiniR4.DriveDC.setMoveGyroPID(kp, ki, kd);
MiniR4.DriveDC.setTurnGyroPID(kp, ki, kd);

IMU

Для угла поворота обычно нужен Yaw:

MiniR4.Motion.resetIMUValues();
double yaw = MiniR4.Motion.getEuler(MiniR4Motion::AxisType::Yaw);

Для угловой скорости вокруг вертикальной оси:

double zRate = MiniR4.Motion.getGyro(MiniR4Motion::AxisType::Z);

Питание

Официальный диапазон входного питания MATRIX Mini R4: 6V ... 24V. Для экспериментов в этом репозитории используется 2S аккумулятор: примерно 6.0V ... 8.4V.

Для 2S аккумулятора:

MiniR4.PWR.setBattCell(2);
float v = MiniR4.PWR.getBattVoltage();

setBattCell(2) не меняет питание моторов. Он задает пороги мониторинга батареи в нижнем STM32: полный заряд 8.4V, номинал 7.4V, нижний порог 6.8V.

Входное напряжение аккумулятора идет на силовую часть платы и влияет на моторы. setSpeed() и setPower() задают команду контроллеру мотора, но реальная скорость и тяга зависят от напряжения батареи, просадки под нагрузкой, веса робота и трения. Поэтому графики из главы 3 привязаны к конкретному питанию теста.

Датчик линии MS-018

Для MS-018 в библиотеке есть MatrixLineTracer. Он дает сырые значения 10 каналов и готовую ошибку линии.

MiniR4.I2C0.MXLineTracer.begin();

uint8_t sensors[10];
MiniR4.I2C0.MXLineTracer.getAllSensors(sensors);
float error = MiniR4.I2C0.MXLineTracer.getError();

Для PID по линии удобнее читать датчик часто и держать цикл простым: датчик → ошибка → поправка моторов.

Глава 5. Движение по энкодерам

В этой главе лежат несколько версий кода движения по энкодерам для двухмоторной базы на M1 и M2. В них нет DriveDC, гиро, Serial и библиотечных поворотов. Только свои функции движения по расстоянию и поворота по энкодерам.

Текущие варианты:

  • MatrixEncoderMotionV0/MatrixEncoderMotionV0.ino — упрощенный профиль: расстояние напрямую превращается в команду setSpeed через smoothstep, без mm/s, ускорения и jerk;
  • MatrixEncoderMotionV1/MatrixEncoderMotionV1.ino — старая версия профиля с targetSpeed, targetAccel, sCurveStopDistance() и переключением разгон/торможение;
  • MatrixEncoderMotionV2/MatrixEncoderMotionV2.ino — новая версия с velocity governor: разрешенная скорость считается по оставшемуся расстоянию, затем профиль плавно догоняется через accel/jerk;
  • MatrixEncoderMotionTest/MatrixEncoderMotionTest.ino — рабочий тестовый sketch, оставлен как промежуточная версия.

Для сравнения профилей без робота:

Основная идея: пользователь задает расстояние в mm или угол в градусах, а код сам считает профиль скорости, синхронизирует моторы по энкодерам и останавливается по фактической остановке колес.

Настройки робота

Ключевые константы:

Константа Значение Зачем нужна
BATTERY_CELLS 2 настройка контроля 2S аккумулятора
WHEEL_DIAMETER_MM 65.0 диаметр колеса для пересчета энкодеров в миллиметры
WHEEL_BASE_MM 142.0 расстояние между колесами для расчета поворота
LEFT_MOTOR_REVERSED false направление левого мотора
RIGHT_MOTOR_REVERSED true направление правого мотора
DEFAULT_DRIVE_ACCEL_MM_S2 2000.0 ускорение по умолчанию для прямого движения
DEFAULT_DRIVE_JERK_MM_S3 35000.0 ограничение рывка для плавного старта/торможения
DEFAULT_TURN_ACCEL_DEG_S2 720.0 ускорение поворота
DEFAULT_TURN_JERK_DEG_S3 10000.0 рывок поворота
DRIVE_SYNC_KP 0.35 сила синхронизации левого и правого энкодера

Старт sketch

В setup() плата инициализируется, включается режим 2S батареи и задаются направления моторов:

MiniR4.begin();
MiniR4.PWR.setBattCell(BATTERY_CELLS);
MiniR4.M1.setReverse(LEFT_MOTOR_REVERSED);
MiniR4.M2.setReverse(RIGHT_MOTOR_REVERSED);

В loop() стоит защита static bool testDone, поэтому тест выполняется один раз. Перед стартом на OLED показывается напряжение батареи, движение начинается только после нажатия BTN_UP или BTN_DOWN.

Текущий тестовый сценарий:

driveMm(500, 300);
turnDeg(90, 180);

То есть робот проезжает 500 mm, потом поворачивает на 90 градусов по энкодерам.

Прямое движение

Главная функция:

driveMm(distanceMm, maxSpeedMmS);
driveMm(distanceMm, maxSpeedMmS, accelMmS2);
driveMm(distanceMm, maxSpeedMmS, accelMmS2, jerkMmS3);

Примеры:

driveMm(500, 300);        // вперед 500 mm, цель 300 mm/s
driveMm(-500, 250);       // назад 500 mm, цель 250 mm/s
driveMm(1000, 500, 600);  // вперед 1000 mm, ускорение 600 mm/s^2

Внутри driveMm() просто вызывает общий движок:

moveTankMm(distanceMm, distanceMm, speed, accel, jerk);

Как работает движение

Алгоритм moveTankMm():

  1. Сбрасывает энкодеры M1 и M2.
  2. Переводит градусы энкодера в миллиметры через WHEEL_DIAMETER_MM.
  3. Считает пройденную дистанцию по среднему значению левого и правого колеса.
  4. Ведет целевую скорость через S-curve: ускорение меняется не резко, а через jerk.
  5. По фактической скорости колес подбирает команду мотора 0..100.
  6. Синхронизирует колеса: если левое ушло дальше правого, левое замедляется, правое ускоряется.
  7. В конце вызывает smartStopDrive().

Синхронизация простая:

syncErrorMm = leftMm - rightMm;
syncCorrection = syncErrorMm * DRIVE_SYNC_KP;

Если робот виляет, первым делом меняется DRIVE_SYNC_KP. Если поправка слишком большая — робот дергается. Если маленькая — хуже держит прямую.

S-curve

В этом sketch скорость не прыгает сразу к целевой. Код отдельно хранит:

  • targetSpeed — текущая целевая скорость;
  • targetAccel — текущее целевое ускорение;
  • jerkMmS3 — насколько быстро можно менять ускорение.

Упрощенно:

targetAccel = approachFloat(targetAccel, desiredAccel, jerkMmS3 * dtS);
targetSpeed += targetAccel * dtS;

Это убирает резкий старт. Чем меньше jerkMmS3, тем мягче начало и торможение. Чем больше jerkMmS3, тем ближе поведение к обычной трапеции.

Энкодерный поворот

Функция:

turnDeg(angleDeg, maxAngularSpeedDegS);
turnDeg(angleDeg, maxAngularSpeedDegS, accelDegS2);
turnDeg(angleDeg, maxAngularSpeedDegS, accelDegS2, jerkDegS3);

Она считает, сколько миллиметров должно пройти каждое колесо:

wheelDistance = wheelBase * pi * abs(angle) / 360

Потом вызывает moveTankMm() с противоположными направлениями колес:

moveTankMm(+wheelDistance, -wheelDistance, ...);

Для отрицательного угла направления меняются местами.

Остановка без тупого delay

smartStopDrive() не просто делает delay(1000). Она:

  1. отправляет моторам setSpeed(0);
  2. включает тормоз;
  3. читает энкодеры;
  4. ждет, пока оба колеса перестанут менять градусы в течение DRIVE.stopStableMs;
  5. выходит не позже DRIVE.stopMaxWaitMs.

Это нужно из-за инерции: мотор может получить 0, но колесо еще чуть докручивается.

Что крутить при настройке

Симптом Что менять
резкий старт уменьшить DEFAULT_DRIVE_JERK_MM_S3
слишком вялый старт увеличить DEFAULT_DRIVE_ACCEL_MM_S2 или DEFAULT_DRIVE_JERK_MM_S3
не держит прямую увеличить DRIVE_SYNC_KP
дергается при синхронизации уменьшить DRIVE_SYNC_KP
расстояние неверное уточнить WHEEL_DIAMETER_MM
угол поворота по энкодерам неверный уточнить WHEEL_BASE_MM

Глава 6. Веб-интерфейс

Sketch MatrixWifiTurnPowerTest показывает, что MATRIX R4 можно использовать не только как автономный робот, но и как маленький Wi-Fi сервер с веб-пультом. Arduino UNO R4 WiFi подключается к домашней сети, запускает HTTP-сервер на порту 80, показывает IP на OLED, а управление открывается из браузера.

Файл sketch: MatrixWifiTurnPowerTest/MatrixWifiTurnPowerTest.ino.

Что делает пример

После загрузки sketch:

  1. робот подключается к Wi-Fi;
  2. на OLED появляется IP-адрес;
  3. с телефона или компьютера в той же сети открывается http://IP_РОБОТА/;
  4. браузер показывает кнопки управления поворотом;
  5. робот отдает статус в JSON: энкодеры, yaw, скорость колес, напряжение батареи.

Это не загрузка прошивки по Wi-Fi. Это веб-интерфейс управления и телеметрии уже запущенного sketch.

Настройка Wi-Fi

Перед загрузкой нужно прописать сеть:

const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASS[] = "YOUR_WIFI_PASSWORD";

Пароль не стоит хранить в публичном репозитории. В текущем sketch оставлены заглушки.

Управление через браузер

Веб-страница отправляет простые HTTP-запросы:

URL Что делает
/ отдает HTML-страницу пульта
/set?p=100 задает команду поворота
/step?d=10 меняет команду на шаг
/stop останавливает моторы
/status возвращает JSON-статус

Команда p сейчас работает в диапазоне от -1000 до 1000. В sketch это сделано через:

mmL.SetDCMotorSpeedRange(1, 0, SPEED_RANGE_MAX);
mmL.SetDCMotorSpeedRange(2, 0, SPEED_RANGE_MAX);

После этого поворот задается через MiniR4.M1.setSpeed() и MiniR4.M2.setSpeed(). Положительное значение крутит робота в одну сторону, отрицательное — в другую.

Синхронизация поворота

Даже при одинаковой команде моторы могут вращаться по-разному. Поэтому sketch сравнивает энкодеры и подправляет команды:

correction = (leftDeg - rightDeg) * TURN_SYNC_KP;
leftPower = basePower - correction;
rightPower = basePower + correction;

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

Телеметрия

/status возвращает примерно такие поля:

Поле Значение
power текущая команда поворота
yaw текущий yaw IMU
m1, m2 градусы энкодеров
lds, rds скорость колес в deg/s
lms, rms скорость колес в mm/s
left, right фактические команды левого и правого мотора
battery напряжение батареи

Страница обновляет статус каждые 500 ms, поэтому можно менять команду и сразу видеть, как реагируют энкодеры.

Безопасность

В sketch есть три простые защиты:

  • кнопки BTN_UP и BTN_DOWN сразу вызывают stopMotors();
  • если команды не приходят дольше COMMAND_TIMEOUT_MS, моторы останавливаются;
  • при потере Wi-Fi или ошибке подключения моторы остаются остановленными.

Ограничения тоже важны:

  • веб-сервер без пароля и авторизации;
  • использовать только в своей локальной сети;
  • не оставлять робота на столе с колесами, которые могут зацепиться;
  • для публичного репозитория не коммитить настоящий Wi-Fi пароль.

Глава 7. Датчик линии

Для движения по линии используется MS-018 MATRIX Line Tracer 10CH. Это 10-канальный датчик линии, который подключается к контроллеру по I2C и подходит для PID-руления по черной линии.

MS-018 MATRIX Line Tracer 10CH

Изображение: MATRIX Robotics, страница MS-018 MATRIX Line Tracer 10CH.

Кратко по официальному описанию:

  • 10 каналов отражения для более точного определения положения линии;
  • I2C-передача данных в контроллер;
  • расчет Error — смещение линии относительно центра датчика;
  • расчет Line Width — ширина/количество активных сенсоров;
  • определение перекрестков: Left, Right, T-junction, Cross-junction;
  • хранение Last Sensor перед потерей линии;
  • встроенная калибровка кнопкой CAL и синий индикатор;
  • питание 3.3V ~ 5V;
  • оптимизация для слабого освещения.

На MATRIX R4 текущая версия датчика используется через I2C0, то есть порт A3:

MiniR4.I2C0.MXLineTracer.begin();
MiniR4.I2C0.MXLineTracer.getAllSensors(sensors);

MatrixMS018JSTTest

Файл sketch: MatrixMS018JSTTest/MatrixMS018JSTTest.ino.

Это тест подключения и чтения датчика. Он:

  • запускает MS-018 на I2C0;
  • читает 10 сырых каналов;
  • считает ошибку линии -4.5 ... 4.5;
  • показывает на OLED Error, Line Width, Last Sensor, Junction Type;
  • рисует 10 столбиков по значениям сенсоров.

Этот sketch нужен первым: если он не видит линию или датчик, PID-код трогать рано.

MatrixLineFollowPIDTest

Файл sketch: MatrixLineFollowPIDTest/MatrixLineFollowPIDTest.ino.

Это классическое движение по линии без ограничения по расстоянию. Логика:

  • кнопка запускает движение;
  • каждые 20 ms читается датчик;
  • ошибка линии идет в PID;
  • PID дает поправку к левому и правому мотору;
  • при потере линии робот тормозит и возвращается в ожидание;
  • кнопка во время движения работает как stop.

Главные настройки:

const int BASE_SPEED = 30;
const int MAX_SPEED = 55;
const float KP = 7.0;
const float KI = 0.0;
const float KD = 18.0;
const int STEERING_SIGN = 1;

Если робот уезжает от линии, первым делом поменять STEERING_SIGN на -1.

MatrixLineDistanceTest

Файл sketch: MatrixLineDistanceTest/MatrixLineDistanceTest.ino.

Это движение по линии на заданное расстояние. Он объединяет:

  • чтение MS-018;
  • PID-поправку по линии;
  • энкодеры M1/M2;
  • S-curve разгон и торможение;
  • остановку по расстоянию в миллиметрах.

Текущий тест:

const long TEST_DISTANCE_MM = 1000;
const int LINE_MAX_SPEED_MM_S = 250;

Результат на OLED:

  • DONE — расстояние пройдено;
  • LOST — линия потеряна;
  • STOP — остановлено кнопкой;
  • TIME — вышел timeout.

Этот sketch полезен для задач, где робот должен не просто ехать по линии, а проехать конкретный участок трассы.

Визуализаторы

Для GitHub Pages добавлена стартовая страница index.html. Через нее можно открыть оба визуализатора:

Эти страницы статические, поэтому их можно открывать локально из файла или через GitHub Pages без сервера.

About

Мне на несколько дней дали MATRIX R4 Robo Set, я развлекался как мог.

Topics

Resources

Stars

Watchers

Forks

Contributors