roboforum.ru

Технический форум по робототехнике.

Как правильно писать сценарии поведения робота?

Re: Как правильно писать сценарии поведения робота?

Dmitry__ » 04 дек 2016, 00:12

smur писал(а):Это слишком категорично
Конечный автомат — абстрактный автомат, число возможных внутренних состояний которого конечно.

Вот именно этого я и ждал, не писал сразу доказательство: все пардигмы - конечный автомат. :)
Доказательство: Все программы исполняются на процессоре, который - конечный автомат.
Вывод: Если ИИ не является конечным автоматом, то его нельзя воспроизвести на существующих процессорах. Шах и мат :)

Re: Как правильно писать сценарии поведения робота?

Scorpio » 04 дек 2016, 00:28

И это правильно. ИИ, для меня во всяком случае, это возможость использовать полученный опыт для саморазвития. Это просто адаптивный алгоритм на конечных автоматах. Но возможности его безграничны. Я уверен, что, когда Виктор Казаринов допилит свой ИИ движок, окажется, что "да это же так просто, и как я сам не догадался". А ИИ будет поставляться в комплекте с конструктором лего.

Re: Как правильно писать сценарии поведения робота?

Dmitry__ » 04 дек 2016, 00:38

Scorpio писал(а):Это просто адаптивный алгоритм на конечных автоматах. Но возможности его безграничны.

Не совсем так.
Пример лунохода Виктора Казаринова - чрезмерно усложнен. Или, как я и говорил, нельзя проверять парадигмы на таком примитивном устройстве, или это доказательство того, что есть более понятные вещи.
Наблюдая разных топ лайн-трайсеров на конечных автоматах, иногда задаешь себе вопрос: "а я бы (ИИ) прошел так трассу?"

Re: Как правильно писать сценарии поведения робота?

smur » 04 дек 2016, 10:16

Так Виктор сразу и написал:
>"Простейшим видом агента является простой рефлексный агент. Подобные агенты выбирают действия на основе текущего акта >восприятия, игнорируя всю остальную историю актов восприятия." Видимо, написание сценария для робота-лунохода в >качестве такого простейшего агента-робота можно обсуждать в данной теме. О других , более сложных видах >интеллектуальных агентов можно говорить после разбора этого простейшего вида.

Так что хотя бы с этим разобраться :) Те. в качестве "кошечек" рассматривается работа с автоматами I (Ну может и II рода), когда состояние системы определяется значениями входных воздействий в текущий (либо в предыдущий) такт. Тут ИИ и не применим, тк его зарезали по глубине предыстории :)

А лайн трейсеры, если нет замкнутых линий, можно построить на комбинационной логике, на 155ЛА3 :)
А если есть замкнутые участки, то без анализа предыстории будешь по кругу бегать.

Re: Как правильно писать сценарии поведения робота?

Angel71 » 04 дек 2016, 10:31

Dmitry__, в пень эту болтологию с частичками души и ии. простая задача и в реальной ситуации можно было проще реализовать на си или ещё чём. но он же ищет на чём делать для разных задач, так что немного усложнив для машинки можно посмотреть, на сколько этот вариант с клипсом подходит. то, что "луноход" простой как валенок это да, только для разных задач и выбор более подходящего подхода может отличаться. из полезного на практике может пригодится прерывание выполнения, параллельные задачи, прокладка маршрута, как организовывать работу с ресурсами у которых возможен только монопольный доступ, хранение и обработка данных об истории действий и/или окружающей среде.
некая простенькая платформа на колёсах или гусеницах, перемещение по клеткам. 3 светодиода (2 индикация поворота, третий для общей индикации). использовать или нет бамперы, дальномеры, энкодеры, датчики цвета,... то другой момент.
1) выполнения списка задач на подобии: из начальной клетки проехать вперёд 2, повернуть направо, проехать вперёд 1, повернуть налево, включить "общий" светодиод, проехать вперёд 4, включить "общий" светодиод. все повороты в этом режиме на 90 градусов и при поворотах мигать соответствующим сетодиодом.
2) из начальной клетки проехать в клетку с определёнными координатами. на пути могут быть клетки "препятствие", которые нужно объезжать. если есть путь, остаться в целевой клетке, если нет, вернться в изначальную.
3) при нажатии на кнопку или получении команды по проводам/радиоканалу начать мигать всеми тремя светодиодамим. при повторном нажатии или получении этой же команды (или команды отмены) прекратить мигать диодами. это будет допустим симуляцией поведения при разряде аккумулятора.
4) опять кнопка/радиоканал. получена команда вернуться в изначальную клетку. текущее выполнение других (всех или только определённых, допустим 1 отменить, а 3 нет) задач полностью прерываются, без дальнейшей возможности выполнения. пока не получена другая команда для отмены этого режима, никакие не отменяемые режимы/задачи не могут выполняться.
5) как и 4, только после получения команды отмены этого режима, прерванные задачи/режимы должны продолжить свою работу. с вариациями. 1 может начать выполняться с начала или проехав в точку в которой было прервано выполнение продолжить выполнение по списку. 2 может вернуться в клетку и продолжить движение в заданную клетку или по полученным данным (клетки в которых можно перемещаться и клетки "препятствие") проложить новый путь.
при прерывании два варианта - немедленно в любой момент или дав возможность немного завершить подзадачу, т.е. допустим при повороте не прерывать, когда он повернулся на 25градуса, а дождаться когда провернётся на 90. аналогично с перемещением по клетке - в любой момент где-то между двумя клетками или дождавшись, когда оно полностью переместиться в следующую клетку.
ещё ввод приоритетов для задач/режимов и ресурсов с монопольным доступом. допустим 1 и 2 с минимальным приоритетом и могут быть прерваны задачами с большим приоритетом. 3 в зависимости от уровня заряда может иметь различный приоритет - 2 если не критически разряжено и 3 если критически. 4 и 5 допустим с фиксированным приоритетом в 2.

Re: Как правильно писать сценарии поведения робота?

Dmitry__ » 04 дек 2016, 11:51

Да я даже код не могу найти в той туче файлов, а это был всего алгоритм в 10 ассемблерных строк :)

Re: Как правильно писать сценарии поведения робота?

Angel71 » 04 дек 2016, 12:07

на перфокартах смотрел? вот один кусок кода
Код: Выделить всёРазвернуть
(defmodule EXECUTOR (import MAIN deftemplate ?ALL) (import SOLVER deftemplate ?ALL))

(defrule EXECUTOR::Action-Forward
?c <- (cycle ?current-cycle)
?f <- (action (name forward) (param ?p) (status request))
  =>
(retract ?f)
(printout t "EXECUTOR::Action=Forward.Step()." crlf)
(assert (action (name forward) (param ?p) (status OK)))            ; Для модуля SOLVER
)

(defrule EXECUTOR::Action-Left
?c <- (cycle ?current-cycle)
?f <- (action (name left) (param ?p) (status request))
  =>
(retract ?f)
(printout t "EXECUTOR::Action=Left.Step()." crlf)
(assert (action (name left) (param ?p) (status OK)))               ; Для модуля SOLVER
)

(defrule EXECUTOR::Action-Right
?c <- (cycle ?current-cycle)
?f <- (action (name right) (param ?p) (status request))
  =>
(retract ?f)
(printout t "EXECUTOR::Action=Right.Step()." crlf)
(assert (action (name right) (param ?p) (status OK)))              ; Для модуля SOLVER
)

с ассемблером это конечно вариант, вот только когда задачи будут посложней и кода будет намного больше, на всей этой тотальной низкоуровневой возне ставится жирный крест с подписью "слишком долго и дорого так разрабатывать, слишком трудно вносить изменения, слишком мало специалистов с нужным уровнем подготовки и т.д. проект закрыт [вы уволены | не хватило средств для завершения проекта | проект уже не актуален]".

Re: Как правильно писать сценарии поведения робота?

Dmitry__ » 04 дек 2016, 13:36

Я не собирался писать на асме :), он был нужен только для сравнения сложности.

Re: Как правильно писать сценарии поведения робота?

smur » 04 дек 2016, 14:07

У Виктора решение отличное и масштабируемое. Если нужно заполнять сценарии и проч в более понятном виде, то можно применить надстройку, которая будет транслировать текстовое описание в язык модулей сценариев. Я же пытаюсь (пока :)) выступать в роли адепта графической визуализации. Чтобы в случаях со сложной логикой можно было видеть работу всех параметров не копаясь в таблицах переходов. В приложении я добавил состояние Конфета в автомате Вперёд. На картинке это легче воспринимается, чем в таблице переходов, а картинку можно сразу однозначно перегнать в код конвертером.
https://www.dropbox.com/s/42a8z6la4nd4w ... 1.jpg?dl=0

Re: Как правильно писать сценарии поведения робота?

Angel71 » 04 дек 2016, 14:44

Dmitry__, если прям для задачи выполнения списка команд "вперёд, направо, стоп" изначально же очевидно, что избыточные навороты. а так это только пример же был, при усложнении задачи предпочтения могут сильно поменяться.
smur, визуализация это всего лишь дополнение/надстройка. очень хочется, прикрути простенькую визуализацию или хоть навороченный графический редактор.

Re: Как правильно писать сценарии поведения робота?

Виктор Казаринов » 04 дек 2016, 15:29

Поясню программу Лунохода1, которую я представил в сообщении: http://roboforum.ru/forum102/topic17000-180.html#p366813
Язык CLIPS позволяет с помощью специального bat файла выполнять некоторые операции.
Ниже представлен файл Lunochod1NoBarrier.bat:
Код: Выделить всёРазвернуть
(defmodule MAIN (export deftemplate ?ALL))
(load Lunochod1/Main.ecl)
(load Lunochod1/SimulatorNoBarrier.ecl)
(load Lunochod1/Mission1.ecl)
(load Lunochod1/Sensor.ecl)
(load Lunochod1/Solver.ecl)
(load Lunochod1/Executor.ecl)
(reset)
(run )

в котором первая строка сообщает, что все шаблоны фактов модуля MAIN экспортируются и становятся доступными для использования в других модулях. В каждом модуле работает отдельный движок продукционных правил, поэтому чтобы передать что-то из одного модуля в другой, нужно экспортировать требуемые конструкции.
Затем последовательно загружаются все файлы с модулями программы.
В конце командой reset очищается память, а командой run программа стартует начиная с модуля MAIN.

Файл Main.ecl с модулем MAIN
Код: Выделить всёРазвернуть
;;;======================================================
;;;     Lunochod V 1.0.0
;;;     MAIN Module
;;;     For ECLIPS Version 6.3
;;;     2016.12.02 Victor Kazarinov
;;;======================================================
;;; Главный модуль программы.
;;;======================================================

; Система должна работать циклически, поэтому нужен факт cycle, обозначающий текущий номер цикла
(deffacts MAIN::cycle-start
(cycle -1)                         ; Начальное значение номера цикла
)

;;;======================================================

(defrule MAIN::Cycle-Start
(cycle -1)
  =>
(printout t "MAIN::Program Lunochod started"  crlf)
)

(defrule MAIN::Cycle-Next                       ; Правило, определяющее последовательность работы всей программы.
?f <- (cycle ?current-cycle)
  =>
(retract ?f)
(bind ?next-cycle (+ ?current-cycle 1))
(assert (cycle ?next-cycle))
(printout t "MAIN::Cycle=" ?next-cycle crlf)
(focus SIMULATOR MISSION SENSOR SOLVER EXECUTOR)
)

Язык CLIPS позволяет писать модульные программы, чем я и воспользовался. В программе Lunochod1 имеются следующие модули: SIMULATOR MISSION SENSOR SOLVER EXECUTOR.

Начнем анализ программы с модуля MAIN.
Перед стартом программы в памяти размещается факт cycle со значением -1 в конструкции deffacts MAIN::cycle-start.
Рассмотрим на примере самого первого правила программы как устроены правила и как они работают:
Код: Выделить всёРазвернуть
(defrule MAIN::Cycle-Start
(cycle -1)
  =>
(printout t "MAIN::Program Lunochod started"  crlf)
)

Шаблон правила задается ключевым словом defrule. MAIN:: определяет принадлежность правила какому-то модулю. В нашем случае это модуль MAIN. Далее следует название правила: Cycle-Start.
После названия следует условная часть правила (ЕСЛИ). (cycle -1) означает, что если в памяти будет обнаружен факт cycle со значением -1, то правило сработает.
Знак => означает ТО и разделяет условия и действия, которые требуется совершить в случае срабатывания правила.
В нашем случае происходит вывод в консоль (символ t) текста "MAIN::Program Lunochod started", который завершается переводом строки (символ crlf).

Как только программа обнаружит в рабочей памяти факт cycle со значением -1, то по шаблону правила Cycle-Start будет создан объект - экземпляр правила, у которого условная часть заполнена конкретными значениями условий.
Правило Cycle-Next:
Код: Выделить всёРазвернуть
(defrule MAIN::Cycle-Next                       ; Правило, определяющее последовательность работы всей программы.
?f <- (cycle ?current-cycle)
  =>
(retract ?f)
(bind ?next-cycle (+ ?current-cycle 1))
(assert (cycle ?next-cycle))
(printout t "MAIN::Cycle=" ?next-cycle crlf)
(focus SIMULATOR MISSION SENSOR SOLVER EXECUTOR)
)

Правило Cycle-Start после использования факта cycle не уничтожает его, а правило Cycle-Next командой (retract ?f) делает это. После этого рабочая память фактов становится пустой. Однако с помощью (assert (cycle ?next-cycle)) правило Cycle-Next создает другой факт cycle со значением, большим на 1, чем было у предыдущего только что удаленного факта cycle.
Следующей строкой (printout t "MAIN::Cycle=" ?next-cycle crlf) осуществляется вывод текста в терминал.
Оператор focus устанавливает последовательность выполнения модулей после того, как в текущем модуле будут исчерпаны все экземпляры правил. Правила могут сработать только один раз для данного конкретного сочетания фактов.
Следующим модулем, который будет исполняться после модуля MAIN - модуль SIMULATOR.

Файл SimulatorNoBarrier.ecl с модулем SIMULATOR для случая, когда на пути лунохода нет препятствий, предельно прост:
Код: Выделить всёРазвернуть
;;;======================================================
;;;     Lunochod V 1.0.0
;;;     SIMULATOR Module
;;;     For ECLIPS Version 6.3
;;;     2016.12.02 Victor Kazarinov
;;;======================================================
;;; Модуль симулятора внешней среды, сенсоров и пользователя.
;;;======================================================

(defmodule SIMULATOR (export deftemplate ?ALL) (import MAIN deftemplate ?ALL))

(defrule SIMULATOR::Mission1-Start                  ; Правило старта Миссии1
?c <- (cycle 0)
  =>
(assert (mission mission1))
(printout t "SIMULATOR::Mission1:Start."  crlf)
)

Он состоит всего лишь из одного правила: когда будет получен факт cycle со значением 0, то создать факт mission со значением mission1. Однажды созданный, этот факт будет существовать в системе до окончания миссии1 и будет являться флагом для работы робота над выполнением этой миссии.
Для нашего удобства в терминал командой (printout t "SIMULATOR::Mission1:Start." crlf) выводится контрольное сообщение.

Файл SimulatorBarrier.ecl с модулем SIMULATOR для случая, когда на пути лунохода имеется препятствие:
Код: Выделить всёРазвернуть
;;;======================================================
;;;     Lunochod V 1.0.0
;;;     SIMULATOR Module
;;;     For ECLIPS Version 6.3
;;;     2016.12.02 Victor Kazarinov
;;;======================================================
;;; Модуль симулятора внешней среды, сенсоров и пользователя.
;;;======================================================

(defmodule SIMULATOR (export deftemplate ?ALL) (import MAIN deftemplate ?ALL))

(defrule SIMULATOR::Mission1-Start                  ; Правило старта Миссии1
?c <- (cycle 1)
  =>
(assert (mission mission1))
(printout t "SIMULATOR::Mission1:Start."  crlf)
)

(defrule SIMULATOR::Barrier-Set                     ; Правило, устанавливающее препятствие на пути робота.
?c <- (cycle 2)
  =>
(assert (barrier detected))
(printout t "SIMULATOR::Barrier Set."  crlf)
)

(defrule SIMULATOR::Barrier-Removed                 ; Правило, устраняющее препятствие на пути робота.
?c <- (cycle 4)
?f <- (barrier detected)
  =>
(retract ?f)
(printout t "SIMULATOR::Barrier Removed."  crlf)
)


В дополнение к тому, что делает модуль SIMULATOR для случая без препятствий, правило SIMULATOR::Barrier-Set устанавливает препятствие на пути робота в цикле 2, а правило SIMULATOR::Barrier-Removed удаляет это препятствие в цикле 4.

Файл Mission1.ecl с модулем MISSION:
Код: Выделить всёРазвернуть
;;;======================================================
;;;     Lunochod V 1.0.0
;;;     MISSION Module
;;;     For ECLIPS Version 6.3
;;;     2016.12.02 Victor Kazarinov
;;;======================================================
;;; Модуль пользовательского сценария.
;;;======================================================

(defmodule MISSION (export deftemplate ?ALL) (import MAIN deftemplate ?ALL) (import SIMULATOR deftemplate ?ALL))

(deftemplate MISSION::command                   ; Шаблон факта команды, поступающей в сенсорный модуль
(slot name)
(slot param (type INTEGER) (default 0))
)

(deftemplate MISSION::answer                    ; Шаблон факта ответа, поступающего из модуля EXECUTOR
(slot name)
(slot param)
)

(deffacts MISSION::mission1-facts               ; Шаблон факта фаз выполнения миссии.
(phase forward1)
)

;;;======================================================

(defrule MISSION::Mission1-Forward1             ; Правило первой фазы Миссии1
?c <- (cycle ?current-cycle)
?f <- (mission mission1)
?m <- (phase forward1)
  =>
(retract ?m)
(printout t "MISSION::Mission1.Command.Forward1(5)" crlf)
(assert (command (name forward) (param 5)))    ; Для модуля SOLVER
(assert (phase right1))
)

(defrule MISSION::Mission1-Right1               ; Правило второй фазы Миссии1
?c <- (cycle ?current-cycle)
?f <- (mission mission1)
?m <- (phase right1)
?n <- (answer (name forward) (param OK))
  =>
(retract ?m)
(retract ?n)
(printout t "MISSION::Mission1.Command.Right1(3)." crlf)
(assert (command (name right) (param 3)))      ; Для модуля SOLVER
(assert (phase left1))
)

(defrule MISSION::Mission1-Left1                ; Правило третьей фазы Миссии1
?c <- (cycle ?current-cycle)
?f <- (mission mission1)
?m <- (phase left1)
?n <- (answer (name right) (param OK))
  =>
(retract ?m)
(retract ?n)
(printout t "MISSION::Mission1.Command.Left1(8)." crlf)
(assert (command (name left) (param 8)))       ; Для модуля SOLVER
(assert (phase end1))
)

(defrule MISSION::Mission1-End1                 ; Правило четвертой фазы Миссии1
?c <- (cycle ?current-cycle)
?f <- (mission mission1)
?m <- (phase end1)
?n <- (answer (name left) (param OK))
  =>
(retract ?m)
(retract ?n)
(retract ?f)
(printout t "MISSION::Mission1.Command.End()." crlf)
(halt)
)

Конструкция deftemplate MISSION::command создает шаблон факта команды, поступающей в модуль SOLVER, а шаблон факта deftemplate MISSION::answer позволяет получить ответ модуля SOLVER о результате выполнения команды.
Конструкция deffacts MISSION::mission1-facts перед началом выполнения модуля MISSION размещает в рабочей памяти факт phase со значением forward1.

Правило MISSION::Mission1-Forward1 срабатывает сразу же, как только управление переходит в этот модуль, т.к. в наличии будут все условия для его срабатывания. Оно удаляет факт фазы, выводит в теминал лог, а также создает факт command для модуля SOLVER с указанием направления движения робота и величиной перемещения. Это правило создает еще факт phase со значением right1, что указывает на следующий этап работы конечного автомата сценария.
Правило MISSION::Mission1-Right1 сработает, если появится дополнительное условие -факт answer от модуля SOLVER с подтверждением полного выполнения предыдущего этапа сценария.
Аналогично работают и все остальные правила. Последнее правило Mission1-End1 не создает новой команды, а завершает работу программы.

Теперь переходим к рассмотрению модулей, описывающим внутреннее устройство робота.
Файл Sensor.ecl с модулем SENSOR:
Код: Выделить всёРазвернуть
;;;======================================================
;;;     Lunochod V 1.0.0
;;;     SENSOR Module
;;;     For ECLIPS Version 6.3
;;;     2016.12.02 Victor Kazarinov
;;;======================================================
;;; Модуль обработки сенсорных данных.
;;;======================================================

(defmodule SENSOR (export deftemplate ?ALL) (import MAIN deftemplate ?ALL) (import MISSION deftemplate ?ALL))

(defrule SENSOR::Barrier-Detected               ; Правило обнаружения препятствия.
?c <- (cycle ?current-cycle)
?f <- (barrier detected)
  =>
(assert (sensor barrier))                      ; Для модуля SOLVER
(printout t "SENSOR::Error: Barrier Detected!"  crlf)
)

(defrule SENSOR::Barrier-Removed                ; Правило определения отстутсвия препятствия.
?c <- (cycle ?current-cycle)
(not (barrier detected))
  =>
(assert (sensor nobarrier))                    ; Для модуля SOLVER
(printout t "SENSOR::Message: No Barrier."  crlf)
)

Правило Barrier-Detected позволяет обнаружить препятствие, если оборудование робота создаст факт barrier со значением detected и внесет его в рабочую память этого модуля. Как видно из кода, во всех правилах здесь, как и в других модулях, присутствует конструкция вида ?c <- (cycle ?current-cycle), которая позволяет привязать выполнение всех правил к текущему циклу работы всей программы.
Если препятствие обнаружено правилом Barrier-Detected, то командой (assert (sensor barrier)) будет создан факт sensor со значением barrier. Этот факт предназначен модулю SOLVER.
Правило Barrier-Removed создает аналогичный факт для модуля SOLVER со значением nobarrier в каждом цикле, если препятствия на пути робота нет.

Файл Solver.ecl с модулем SOLVER:
Код: Выделить всёРазвернуть
;;;======================================================
;;;     Lunochod V 1.0.0
;;;     EXECUTOR Module
;;;     For ECLIPS Version 6.3
;;;     2016.12.02 Victor Kazarinov
;;;======================================================
;;; Модуль принятия решений.
;;;======================================================

(defmodule SOLVER (export deftemplate ?ALL) (import MAIN deftemplate ?ALL) (import MISSION deftemplate ?ALL) (import SENSOR deftemplate ?ALL))

(deftemplate SOLVER::action         ; Шаблон факта действия, поступающего в модуль EXECUTOR
(slot name)                        ; Название действия.
(slot param)                       ; Параметр действия.
(slot status)                      ; Статус действия.
)

;;;======================================================

(defrule SOLVER::Decision-Motion-Start
?c <- (cycle ?current-cycle)
?f <- (sensor nobarrier)
?n <- (command (name ?motion) (param ?p))
  =>
(retract ?f)
(retract ?n)
(printout t "SOLVER::" ?motion ".Start()." crlf)
(assert (action (name ?motion) (param (- ?p 1)) (status request)))         ; Для модуля EXECUTOR
)

(defrule SOLVER::Decision-Motion-Cycle
?c <- (cycle ?current-cycle)
?f <- (sensor nobarrier)
?n <- (action (name ?motion) (param ?p) (status OK))
  =>
(retract ?f)
(retract ?n)
(if (> ?p 0)
   then
    (printout t "SOLVER::" ?motion ".Continue()." crlf)
    (assert (action (name ?motion) (param (- ?p 1)) (status request)))       ; Для модуля EXECUTOR
   else
    (printout t "SOLVER::" ?motion ".End()." crlf)
    (assert (answer (name ?motion) (param OK)))             ; Для модуля MISSION
  )
)

В этом модуле конструкция deftemplate SOLVER::action создает шаблон факта, который позволяет модулю SOLVER отправлять команды в модуль EXECUTOR и получать от него подтверждение выполнения команд в слоте status факта action.

Правило SOLVER::Decision-Motion-Start в случае, если нет препятствия и имеется факт command с параметрами срабатывает и среди прочего создает факт action для модуля EXECUTOR. Наследники этого факта затем будут циркулировать в программе до тех пор, пока не выполнятся все шаги. Количество шагов указано в слоте param этого факта.
Циклическое выполнение обеспечивает правило SOLVER::Decision-Motion-Cycle, которое при поступлении в последующих циклах от модуля EXECUTOR факта action со слотом status равным OK вырабатывает факт-наследник action с уменьшенным на 1 значением параметра param.

Файл Executor.ecl с модулем EXECUTOR:
Код: Выделить всёРазвернуть
;;;======================================================
;;;     Lunochod V 1.0.0
;;;     EXECUTOR Module
;;;     For ECLIPS Version 6.3
;;;     2016.12.02 Victor Kazarinov
;;;======================================================
;;; Модуль выполнения действий.
;;;======================================================

(defmodule EXECUTOR (import MAIN deftemplate ?ALL) (import SOLVER deftemplate ?ALL))

(defrule EXECUTOR::Action-Forward
?c <- (cycle ?current-cycle)
?f <- (action (name forward) (param ?p) (status request))
  =>
(retract ?f)
(printout t "EXECUTOR::Action=Forward.Step()." crlf)
(assert (action (name forward) (param ?p) (status OK)))            ; Для модуля SOLVER
)

(defrule EXECUTOR::Action-Left
?c <- (cycle ?current-cycle)
?f <- (action (name left) (param ?p) (status request))
  =>
(retract ?f)
(printout t "EXECUTOR::Action=Left.Step()." crlf)
(assert (action (name left) (param ?p) (status OK)))               ; Для модуля SOLVER
)

(defrule EXECUTOR::Action-Right
?c <- (cycle ?current-cycle)
?f <- (action (name right) (param ?p) (status request))
  =>
(retract ?f)
(printout t "EXECUTOR::Action=Right.Step()." crlf)
(assert (action (name right) (param ?p) (status OK)))              ; Для модуля SOLVER
)

Этот модуль совсем прост. Для каждого направления движения имеется по одному правилу, которое срабатывает при получении из модуля SOLVER факта action с соответствующим значением слота name. При срабатывании каждого правила робот делает элементарный шажок в требуемом направлении, что выражается пока лишь в выводе на теминал логирующего сообщения. После этого правила создают ответный факт action в модуль SOLVER. У этого факта все слоты кроме последнего совпадают с тем фактом action, по которому это правило сработало.
Последний раз редактировалось Виктор Казаринов 04 дек 2016, 16:51, всего редактировалось 5 раз(а).

Re: Как правильно писать сценарии поведения робота?

Dmitry__ » 04 дек 2016, 16:05

Виктор Казаринов писал(а):Поясню программу Лунохода1

Спасибо, так понятнее...

smur, совершенно случайно, разбираясь с foma и морфологическими анализаторами, открыл для себя Graphviz.
http://linuxshare.ru/docs/misc/graphviz.html
http://lib.custis.ru/Graphviz
Если ты знал, то ой :)

Re: Как правильно писать сценарии поведения робота?

smur » 04 дек 2016, 17:28

Спасибо!
Но интереснее не перегонять текст в графы, а рисовать в графах логику программы и перегонять в текст.
А в LabVIEW вообще разработка идёт в графике.
https://ru.wikipedia.org/wiki/LabVIEW
По языкам визуального программирования ссылка:
http://blog.interfacevision.com/design/ ... snapshots/

Re: Как правильно писать сценарии поведения робота?

Scorpio » 04 дек 2016, 18:12

В симуляторе, кстати, отсутствует команда "стоп", с высшим приоритетом, чем "пуск". Всетаки для работы с CLIPS надо полностью перестраивать мозги. Потом его можно использовать только как добавку к С. Ведь робот, кроме логики поведения, должен еще смотреть, слышать, говорить, крутить колеса и т.д. Еще мне не нравится, что одна строчка сценария {Вперед(50),Вправо(30),Влево(80),Звук("ОК")} порождает такое огромное количество кода. Вправо(30),кстати, это макрос (повернуть на 90°+ проехать вперед 30 см.) Видимо CLIPS хорошо использовать для задач типа интеллектуальной базы знаний. Но, может я и не прав.
Графы smura вроде хороши тем, что это стандарт. Но без текстового описания каждой буковки - хрен в них разберешься. Не понятно, что делают загибающиеся на себя стрелочки. "Событие расстояние", например. Может оно движение останавливает, а может еще что. Если нарисовать все фазы движения, то что к каждой из них надо подрисовывать стрелочки с "препятствием" и "конфетой"? Так они, как ёжики будут.
Angel71 писал(а): но он же ищет на чём делать для разных задач

Причем без привязки к конкретному языку (как я уже много раз говорил), что мне важны общие принципы, которые я могу применить на C#, для винды, на джаве для андроида и даже на ардуине.
Туже парадигму CLIPS, я могу применить на С, просто как стиль "факты-правила-действия", также, как и организовать принцип "сигнал - слот". А может и нет никакого универсального стиля, а все зависит от конкретной задачи.

Re: Как правильно писать сценарии поведения робота?

Виктор Казаринов » 04 дек 2016, 19:05

Scorpio писал(а):В симуляторе, кстати, отсутствует команда "стоп", с высшим приоритетом, чем "пуск".
В данной реализации робота команда "стоп" не понадобилась, т.к. если в каком-то цикле будет отсутствовать команда движения, то робот немедленно остановится. В CLIPS "стоп" делается элементарно.
Scorpio писал(а): Всетаки для работы с CLIPS надо полностью перестраивать мозги.
Это не такая сложная перестройка, как в программировании на языке Forth.
Scorpio писал(а):Потом его можно использовать только как добавку к С. Ведь робот, кроме логики поведения, должен еще смотреть, слышать, говорить, крутить колеса и т.д.
Такая интеграция уже заложена в CLIPS и среди документации имеется многостраничный документ по использованию совместно с другими языками: C, C++, Java и др. Можно как добавлять свои функции в CLIPS, так и встраивать CLIPS в программы на др. языках.
Scorpio писал(а):Еще мне не нравится, что одна строчка сценария {Вперед(50),Вправо(30),Влево(80),Звук("ОК")} порождает такое огромное количество кода.
Код сценария заключен в файле Mission1.ecl. Если этого там кода много, то на том же CLIPS запросто пишем интерпретатор в одну страницу кода с языка наподобие того, как я вначале с пом. правил ЕСЛИ-ТО:
-------------------Правила миссии 1-----------------------
Правило01: ЕСЛИ МИССИЯ=МИССИЯ1 ТО СоздатьФакт(ВПЕРЕД1)
Правило02: ЕСЛИ МИССИЯ=МИССИЯ1 И ФАЗА=ВПЕРЕД1 ТО Вперед(ВПРАВО1, 50)
Правило03: ЕСЛИ МИССИЯ=МИССИЯ1 И ФАЗА=ВПРАВО1 ТО Вправо(ВЛЕВО1, 30)
Правило04: ЕСЛИ МИССИЯ=МИССИЯ1 И ФАЗА=ВЛЕВО1 ТО Влево(ЗВУК1, 80)
Правило05: ЕСЛИ МИССИЯ=МИССИЯ1 И ФАЗА=ЗВУК1 ТО Звук(СТОП, "ОК")
--------------End of Правила миссии 1---------------------
И тогда на здоровье программируйте именно на таком или на каком-то еще придуманном языке.
Весь остальной приведенный мною код - это симулятор и внутреннее устройство робота, которые при разных сценариях, подобных приведенному выше, не потребуется изменять.
Scorpio писал(а):Вправо(30),кстати, это макрос (повернуть на 90°+ проехать вперед 30 см.)
Да, я это знаю и тут я предельно упростил самую первую реализацию, чтобы не заслонять подробностями код, но это очень легко поправить. Хотя было бы логичнее в качестве параметра у команды "Вправо" указать градус поворота, а уже следующей командой "Вперед" указать расстояние перемещения.


Rambler\'s Top100 Mail.ru counter