Технический форум по робототехнике.
Scorpio » 22 ноя 2016, 05:24
Имеется в виду правильная организация программы на ПК на языке высокого уровня (но не каком-то специальном).
Конкретный пример: ПК управляет манипулятором через СОМ порт. Дает команду переместить манипулятор, дожидается от него подтверждения, что движение закончено, задает следующее движение (Взять деталь - перенести на новое место - повернуть - положить и т.д.) Также могут возникнуть дополнительные события (например нажата кнопка "отмена"), которые должны прервать текущее действие и перейти на другую ветку сценария. Например, при отмене действия, манипулятор должен свернуться в исходное положение. Но, если он уже успел взять деталь, то должен прежде вернуть ее на место.
Я всегда делал так:
- Циклические операции манипулятора помещал в функцию "сценарий", в которой был набор действий, выбираемых по
swich(Step){case 1: {} case 2: {}…..}
- При очередном событии (в основном приход данных в СОМ порт) менял номер шага Step и однократно выполнял эту функцию.
Когда это простая итерация, то все достаточно удобно и наглядно. Но, когда возникают события, требующее свернуть с прямого пути, появляется куча запутанной логики, в которой мне самому даже сложно разобраться, спустя время.
Как это делается вообще?
Dmitry__ » 22 ноя 2016, 06:12
Scorpio писал(а):Как это делается вообще?
Использовать то самое страшное слово - goto. Без вариантов

Для наглядности можно таблицей переходов. Еще можно делать как обработчик ошибок:
Пример на vb6:
On Local Error 'включить слежение
On Local Error Resume Next 'вернуться в код в место за возник. ошибкой
On Error GoTo 0 'выкл. слежение за ошибками
А называется это все - "мои программы стали сложнее, а я более асинхронным"
Добавлено спустя 3 минуты 25 секунд:Абзац: Обработка ошибок
https://habrahabr.ru/post/175947/
Scorpio » 22 ноя 2016, 07:30
Да, может быть. Работает, конечно, и так, как у меня. Но код трудночитаемый. Я тут достал из чулана своего манипулятора, который
в шашки играет. Да бы переписать его под ардуино (был на лего) и современную винду. А потом может продать по цене запчастей с исходниками, т.к. "роботы должны служить людям". Посмотрел свой код. Ни хрена не понять сразу. Сумбурно как-то куча флагов, блокировок в разных местах. Разобрался в конце концов, но кучу времени убил. Хочется красиво как-то написать, чтобы самому приятно смотреть было.
Dmitry__ » 22 ноя 2016, 15:46
Scorpio писал(а):Работает, конечно, и так, как у меня. Но код трудночитаемый.
Код всегда трудночитаемый, после длительной паузы. Про чужой код вообще молчу.
Scorpio писал(а):Хочется красиво как-то написать, чтобы самому приятно смотреть было.
Только обильное количество комментариев в коде. Не придумали еще такой язык, который было бы сразу красиво и понятно.
Можно попробовать разные парадигмы, например обьектно-ориентированный. Создаешь обьекты с определенными функциями/свойствами и управляешь только этими свойствами. Такой способ дробит сложность понимания на более мелкие изолированные. Но это все только пробы пера человечества. Мы находимся на самой низшей ступени программирования

Вспомни, еще 20 лет назад в обьяснялках на си был пункт - быстрое набивание кода, сокращенные символы, всякие !||={[* и ТОННЫ скобочек (((((((*)))))))) . Теперь про это не вспоминают, ибо любой редактор умеет копипастить.
Повторюсь - подробные комменты - лучший путеводитель по своему коду. Я например, иногда специально перестаю писать комменты - привязываю к себе клиента. Никакой бит секретности не нужен. Быдлокод - лучшая защита от не стрессоустойчивого хакера.
Scorpio » 22 ноя 2016, 19:03
Dmitry__ писал(а): Мы находимся на самой низшей ступени программирования

Во во. Но, если ты уже на низшей,то я еще выглядываю со дна подвала

И все же должна быть какая-то общая концепция написания сценариев асинхронного управления роботом. Для робота - шашиста это не столь актуально, т.к. он достаточно простой. Мало событий и ветвлений. У какого-нибудь сервисного робота их будет в сотни раз больше. Т.е. имеем в одной руке кучу событий, в другой - кучу действий. Теперь надо описать логические связи, чтобы глядя на код можно было бы представить весь процесс. Ну и коменты, конечно.
Dmitry__ » 22 ноя 2016, 20:10
Кста, в кьюте есть слоты, сигналы и коннекты: Можно делать связи между событиями и функциями. Как раз асинхронное программирование. Удобная штука, можно в графич. режиме соединять проводочки, можно описывать в текстовом файле:
- Код: Выделить всё • Развернуть
connect(spinBox_Test, SIGNAL(valueChanged(int)), horizScrollBar_Test, SLOT(setValue(int)));
connect(spinBox_Scaling, SIGNAL(valueChanged(int)), horizScrollBar_Scaling, SLOT(setValue(int)));
connect(spinBox_PositLimitMax, SIGNAL(valueChanged(int)), horizSlider_PositLimitMax, SLOT(setValue(int)));
https://habrahabr.ru/post/50812/
SkyStorm » 22 ноя 2016, 20:26
Есть такая штука как Конечные автоматы и Машина состояний.
В простейшем случае для Ардуино это может быть CASE.
Обычно у роботов - не так много состояний и они легко описываются.
Виктор Казаринов » 22 ноя 2016, 21:05
Да, SkyStorm прав, если робот имеет не очень большое количество внутренних состояний, то можно использовать автоматный стиль программирования:
https://en.wikipedia.org/wiki/Automata-based_programming
Dmitry__ » 22 ноя 2016, 22:18
Ну это совсем просто, думаю этот порог и был преодолен.
Scorpio » 22 ноя 2016, 22:21
Угу. "Существуют также предложения по использованию автоматного программирования в качестве универсального подхода к созданию компьютерных программ вне зависимости от предметной области."
В свое время, когда я развлекался с "Ванессой", я помню собирался придумать для нее собственный язык сценариев под ее API, основанный на следующих принципах:
- любые повторяющиеся действия описываются в виде "секвенций" - последовательностей шагов, которые могут включать в себя субсеквенции,
- каждая секвенция имеет набор условий для ее запуска, а каждый шаг - условия перехода на следующий шаг,
- единовременно может выполняться лишь одна секвенция.
- выполнение секвенции до ее окончания м.б. прервано при запуске другой секвенции, имеющей высший приоритет над выполняемой.
Потом решил не тратить на это время, и писать сценарии прямо в программе. Но,... получилось все совсем не так просто и красиво, как задумывалось.
Так вот. Описаный выше принцип последовательностей, предполагает, что в конце каждого шага, программа взводит некий флаг, и запускает бесконечный цикл ожидания. Сигнал (событие) сбрасывает флаг и разрешает идти дальше.
Другой подход, как я писал в первом посте, что программа не висит в цикле. А при возникновении события, сигнал запускает какой-либо шаг, в зависимости от условий. Что технически тоже самое, но первый способ смотрибельнее. Какой из них более правильный?
smur » 22 ноя 2016, 22:31
Делая робота удалённого присутствия Rasp+Ardu (в качестве хобби и за маленькой дочкой присматривать, когда она одна остаётся дома) стал путаться в логике построения программы (команды по WEB + автоматич. движение + коррекция итп) даже рисуя сначала алгоритмы (до этого делал маленьких роботов для поиска выхода из лабиринта и проч. несложных). В итоге отыскал на просторах интернета тему конечных автоматов (как цель - построение автоматизированных объектов управления). Сейчас изучаю и пытаюсь применить на практике. Этот подход позволяет подходить к проблеме уже осмысленно, тк есть серьёзная теоретическая база. Состояний может быть много. Но есть управляющие состояния (лучше мало) и вычислительные состояния (сколько угодно) дело в подходе и грамотной декомпозиции, см. материалы
http://is.ifmo.ru/works/tech_aut_progДля ознакомления советую прочитать на этом сайте:
Автоматное программирование и робототехника.pdf
Далее хороший материал:
Автоматное программирование.pdf
Санкт-Петербургский государственный университет
Информационных технологий, механики и оптики
Кафедра «Компьютерные технологии»
Н. И. Поликарпова, А. А. Шалыто
Dmitry__ » 23 ноя 2016, 00:49
Scorpio писал(а): А при возникновении события, сигнал запускает какой-либо шаг, в зависимости от условий. Что технически тоже самое, но первый способ смотрибельнее. Какой из них более правильный?
Естественно более правильный второй способ, сложные программы должны быть только событийными. Иначе будет как в ссылке на вики, одни блокировки while:
- Код: Выделить всё • Развернуть
do {
do
c = getchar();
while(c == ' ');
while(c != EOF && !isspace(c) && c != '\n') {
putchar(c);
c = getchar();
}
putchar('\n');
while(c != EOF && c != '\n')
c = getchar();
} while(c != EOF);
return 0;
Оно конечно красивее, но абсолютно нерабочее в сложной программе, т.к. такие блокировки не позволят написать код, адекватно реагирующий на внешние события. Будет как кино с заморозкой кадра для подгрузки буфера:)
Отсюда вырисовывается очередная парадигма - Событийно-ориентированное программирование.
Добавлено спустя 6 минут 56 секунд:Кста, когда пишется начальный код, часто используются всякие Wait, но когда программа начинает обретать функциональность, подключаются и настраиваются всякие аппаратные таймеры, то все эти Wait должны быть полностью исключены из кода. Концепция задержек полностью меняется, соотв. меняется и стиль программирования.
Вообще, любое зацикливание в коде - моветон, разрешено только ардуинщикам

Angel71 » 23 ноя 2016, 00:51
да никакой не правильней - вариантов море и всё зависит от того, что именно вам проще в реализации и понимании.
можно и на конечном автомате, совсем простенькое на кейсах или небольшую библиотеку написать/найти (много гуглится по "fsm arduino"). при необходимости события и "чёрная доска" для хранения данных вполне прикручиваемые.
сдались вам эти количества состояний, сами по себе они проблемы не представляют. с сотнями и более всё может быть просто и наглядно, а может уже и на паре десятков попытка реализации будет жуткой мукой с кучей костылей, а от мысли что нужно внести небольшие изменения в логику работы у вас волосы дыбом становится будут от ужаса. немного возможности языка, железо, на котором это работает и прочие мелочи. а сильно влияет, допустим связанность состояний - какая логика работы, т.е. как из каких состояний переключается в другие. сейчас вот эта переменная такая, а в этой такое значение, значит нам нужно сделать то-то и то-то (оно же может быть выделено в ещё одно состояние) и переключиться вот в такое состояние. для шахмат главное продумать реализацию и особых проблем с машиной состояний быть не должно, хотя в любом случае машину состояний использовать лучше или смешивая с другими подходами или когда совсем всё простенькое, иначе очень легко и быстро это может превратиться в жуткие костыли на костылях и неоправданно большие затраты на реализацию. если прям машина состояний и была реализована, нужно хорошенько подумать ещё раз над реализацией и может вы поймёте как всё переделать что бы стало проще и наглядней.
из простого ещё есть поведенческие деревья, с ними чуть больше возни с реализацией кода деревьев, зато потом чуть проще в реализации логики. последовательности действий делаются элементарно, можно даже с такими вещами, как случайный порядок выполнения последовательности. при реализации чуть проще будет, если в языке есть yield. как и с машиной состояний, к деревьям можно черную доску, события и прочие такие вещи делать. и не обязательно в чистом виде реализовывать, можно совмещать с другими подходами и/или немного расширять, допустим вводя параллельные ветки выполнения и прерыватели.
ещё есть goap и куча других подходов, но вроде о них пока рано.
с вэйтами эт просто не нужно в лоб в спячку мк отправлять или в цикле крутиться и будет всё хорошо. вообще есть подозрение, что вы всё в лоб реализуете. почитайте что такое yield, если в используемом языке его нет или он по каким-то причинам не подходит, что-то подобное можно на указателях делать.
SkyStorm » 23 ноя 2016, 01:24
Прочитал текст последнего сообщения - по результатам бан на сутки за многократное нарушение 5.1.8.
Scorpio » 23 ноя 2016, 01:26
Речь всеже идет о программе на ПК под винду, а не на дуне. Бесконечные циклы страшны лишь психологически, если они не вешают намертво свой процесс, а разрешают события. Любая программа - это бесконечный цикл. Если приложение вывело свое окно и ждет клика, то программа понятное дело не стоит, а продолжает крутиться. Даже в "большой" программе управления роботом с ПК не обойтись без пауз, которые по сути теже циклы. Зато, когда читаешь код, явно видишь: тут начало, тут мы ждем, тут идем дальше. Так что насчет событийного подхода - не уверен, хотя сам сейчас пользуюсь именно им.
Статья по ссылке smur понравилась. Видимо правильно придерживаться стиля автоматного программирования.
Т.к. я еще только учусь писать серьезные программы для роботов, хотелось бы научиться сразу правильно.