Вчера поздним вечером - ранней ночью появилось немного свободного времени, решил потратить его на вопрос определения "точности" работы трихограммницы.
Решил, так как на глаза попалась новоразработанная "мелкокоптерная" трихограммница, наличие которой я как-то вообще выпустил из внимания. Пока не привык воспринимать эту "цацку" как настоящую трихограммницу
А и правда, почему бы на ней не проверить?
Ничего, что моторчик в ней стоит другой, главное, что алгоритмы управления моторчиком точно те же, что и в "больших", "взрослых" трихограммницах. Проверяем то мы как раз алгоритм. А на заведомо маломощном и таком "игрушечном" моторчике все возможные "косяки" алгоритма проявятся быстрее и нагляднее. Что нам, собственно, и требуется.
В первую очередь стал продумывать алгоритм проверки.
Вернее, сначала нужно определить "цель лабораторной работы", а уже потом методику и инструменты. Чисто по научному)
Итак, Цель: Определить точность обеспечения заданной дозировки в условиях переменной скорости движения и переменной нагрузки на дозирующее колесо.
Другими словами: насколько точно моторчик будет поддерживать необходимую расчетную скорость вращения как при динамическом изменении расчетной скорости (а она меняется в зависимости от скорости полета), так и при динамически изменяющихся условиях работы (разная нагрузка на колесо дозатора).
Методика:1) Определяем, сколько
Нужно высыпать трихограммы при заданных параметрах работы.
- Можно простым способом - по
конечному результату на основе
средней скорости "полета", но этот способ не позволяет отследить процесс в динамике - то есть, если во время работы моторчик некоторое время "пересыпал", а потом "недосыпал", в результате мы можем получить "хороший" показатель точности при фактически плохой равномерности внесения по полю.
- Можно фиксировать необходимый расчетный объем внесения в короткие промежутки времени, а общий объем получить сложением этих объемов. В таком случае, если моторчик не будет работать "как надо", это можно наглядно увидеть в любой момент времени.
Я выбрал второй способ, как более точный и наглядный. Период фиксации расчетного объема сделал 100 микросекунд, то есть, 10 раз в секунду. Потому, что GPS у меня работает на 10 Гц, и именно с такой периодичностью обновляет данные о скорости полета... соответственно, и необходимый объем сброса трихограммы программа вычисляет тоже 10 раз в секунду, и коррекцию оборотов моторчика делает тоже 10 раз в секунду.
итак, добавляю строчку в программу:
valtarg = valtarg + RPM * 696 / (60000 / period);где:
valtarg - общий расчетный объем внесения с начала работы дозатора. Здесь он выражается в количестве сигналов энкодера, из которого объем трихограммы в миллилитрах получаем обычным умножением сигналов энкодера на коэффициент, определенный при калибровке дозатора... то есть, это можно пересчитать и в миллилитры, но проверка тогда получится более грубой, так как на 1 мл может приходиться около 1000 импульсов энкодера, и поэтому в миллилитрах точность измерения упадет соответственно в 1000 раз.
RPM - расчетная скорость вращения моторчика.
RPM * 696 - переводим "обороты в минуту" в "количество сигналов энкодера в минуту". У меня на 1 полный оборот дозатора приходится 696 импульсов энкодера для данного моторчика.
RPM * 696 / (60000 / period) - сколько по расчетам за данный период времени (100 мс) должно получиться сигналов энкодера (или объема сброса трихограммы в пересчете).
2 Определяем, сколько реально высыпалось трихограммы.
Ну, здесь ничего прописывать не пришлось, так как это вычисляется программой изначально. Берется сумма фактических сигналов энкодера и умножается на коэффициент, определенный пр калибровке. То есть, сколько сигналов энкодера соответствует реально высыпанному дозатором миллилитру трихограммы.
Так как для максимальной точности измерений я решил считать не в миллилитрах, а в сигналах энкодера, то просто берем сумму сигналов без умножения на коэффициент.
3 Сравниваем фактический объем внесенной трихограммы с расчетным (математически идеальным) объемом.
Снова же, для большей точности сравниваем не миллилитры, а сигналы энкодера.
valdev = valtarg - val2;где
valdev - эта самая разница между желаемым и реально полученным.
val2 - сумма реальных сигналов энкодера, полученных с начала работы дозатора.
4 Выводим результаты для наблюдения:
Serial.print ("Расчет: ");
Serial.print (valtarg);
Serial.print (" Факт: ");
Serial.print (val2);
Serial.print (" Разбежность (расчет - факт): ");
Serial.print (valdev);
Serial.print (" Разбежность %: ");
Serial.println ((valdev / (val2 * 0.01)), 2);
Само собой, мы можем смотреть результаты не в сигналах энкодера, а в объеме трихограммы, для этого достаточно просто каждую выводимую переменную умножать на коэффициент калибровки.
Тогда получим, допустим, не 1345734 сигнала, а 1346 мл. Но в сигналах во много раз точнее и нагляднее.
5 Обеспечиваем условия эксперимента, чтобы его можно было провести за столом, с выводом процесса на монитор:
- Колесо дозатора должно быть "нагружено" и нагрузка эта должна меняться в течение времени (для усложнения условий работы). Для этого ставлю дозирующее колесико "не по размеру" - с чуть большим диаметром, чем нужно, и с небольшим эксцентриситетом.
Это позволяет не мусорить манкой при достижении того же эффекта.
- Так как дозировка прямо пропорционально связана со скоростью полета, при изменении дозировки мы получим совершенно тот же эффект, что и при изменении скорости полета. В формуле не важно какой из двух множителей менять.
Это позволяет проводить измерения "не на ходу".
Собственно, можно прописать функцию, которая будет в процессе работы программы динамически изменять "скорость полета", но результат будет тот же, что и при ручной подстройке дозировки.
6 Проводим измерения.
Мне самому любопытно было узнать, совпадут ли результаты измерений с реальными данными по точности работы аппаратуры...
Итак,
по результатам:
Это скриншот на первых минутах работы:
В процессе кручу регулятор дозировки, моторчик отрабатывает изменения оборотов. Да, при быстром уменьшении дозировки он немного "пересыпает", при быстром увеличении - "недосыпает"
это очень наглядно видно на мониторе по изменению значения "Разбежность".
Однако, как я ни крутил ту настройку, достичь 1% погрешности у меняя так и не получилось. А через некоторое время мне просто надоело, потому, что результат по точности был один и тот же.
Вот крайний скриншот:
То есть, на 1 расчетном "килограмме" он "пересыпал" 9 грамм.
Кстати, я так и не понял, почему оно именно "пересыпает", а не "недосыпает". Скорее всего, причина в инерции ротора самого моторчика - это сказывается при отработке уменьшения оборотов, ведь мы управляем только педалью "газ", а педали "тормоз" у нас нет. Тормозит только за счет естественного трения колеса дозатора в манке и уплотнителе.
Реверсивное переключение мотора для торможения я делать не буду. Оно того не стоит. Да и не бывает в реальном полете слишком быстрого уменьшения скорости. Даже на коптере, где это реально сделать, резкое динамичное торможение не выгодно по соображениям экономии электроэнергии - мы проверяли.
В общем, результаты замеров получились +- примерно такими же, как результаты с реальных полетов. Без сюрпризов и неожиданных научных открытий.
Всего дозатор сделал 1323214 / 696 = 1901 оборот. А по расчетам должен был сделать в идеале
1311231 / 696 = 1884 оборота.
"Накрутил" 17 лишних оборотов.
При средней скорости вращения 80 об/мин дозатор работал у меня 24 минуты. Примерно столько же летает хороший "полевой" квадрокоптер на трихограмме.
А дальше, раз я уже добрался до прошивки, я сделал то, что предлагал сделать в недавнем своем сообщении - реализовать
алгоритм "идеальной точности", с двойной проверкой, включающий и сверку с расчетным количеством внесения трихограммы.
То есть, программа должна не только заставить моторчик вращаться точно в соответствии с расчетной скоростью оборотов, но и постоянно сверять расчетный "идеальный" объем внесения с реальным результатом, внося дополнительную корректировку в обороты моторчика, чтобы получить
идеальное совпадение в любом режиме работы и в любых условиях работы.
Сверку и корректировку делаю традиционно с частотой 10 раз в секунду.
Звучит круто, а на самом деле "умный алгоритм" выглядит так:
if (RPMreal < RPM) {
pwmOut = pwmOut + (RPM - RPMreal) * 0.5 + valdev * 0.01;
// pwmOut = pwmOut + (RPM - RPMreal) * 0.5;
}
if (RPMreal > RPM) {
pwmOut = pwmOut - (RPMreal - RPM) * 0.5 + valdev * 0.01;
// pwmOut = pwmOut - (RPMreal - RPM) * 0.5;
}
Всего-то и изменений.
А работает так: если реально "не досыпало", моторчик чуть-чуть "добавит газу", пока разница между расчетным и реальным не исчезнет. Ну и наоборот.
Кстати, этот алгоритм у меня давно реализован для импульсного режима работы моторчика (когда требуются болезненно малые обороты двигателя). Немножко иначе реализован, так как там управляется не скоростью моторчика, а длительностью его работы, но принцип тот же.
А теперь вот и для работы в режиме непрерывного вращения прописано. Ок... 1% неточности - это тоже неточность. Будем стремиться к идеальному)
Проверяю... При проверке кручу регулятор дозировки так, что обороты двигателя меняются от 154 об/мин до 30 об/мин (с заходом в импульсный режим) и обратно.
Эффект снимаю на видео:
В общем, теперь по любому "дебет с кредитом сойдутся". И если программа "присудит" к внесению на поле, допустим, ровно 4567 миллилитров, то ровно столько и внесется.
Ну.... если моторчик не вынужден будет вращаться с физически недоступной для себя скоростью, конечно.