#anylogic
Вопрос:
после создания нескольких моделей с использованием предопределенных библиотек я создаю модель с нуля. В этой модели мне нужно несколько разных агентов, обменивающихся информацией между собой, и я сделал это возможным, используя динамические переменные и делая их видимыми из верхнего агента. Соединители будут соединять блоки. На рисунке один пример того, что я сделал и что я имел в виду.
Поскольку у меня много информации для обмена, я создал одну переменную для ввода и одну для вывода, используя опцию «Массив» и используя правильные размеры. Мне было интересно, могу ли я сделать их более чистыми и иметь лучшую функциональность, используя порты. Я видел, как они подключались к уже существующим библиотечным компонентам, но никогда в агенте, созданном с нуля. В документации я прочитал, что я мог бы использовать команды «port.send (obj)» и «port.receive (obj)», но я ничего не мог сделать. Итак, мой вопрос: можно ли использовать порты для отправки объектов через код (возможно, агенты, динамическую переменную или что-то еще) между агентами? Если да, то как запустить действие приема в целевом агенте? Заранее большое спасибо! P
Комментарии:
1. Я рекомендую использовать соединения Agent link для передачи сообщений, если вы находитесь на уровне от начального до среднего. После этого используйте пользовательскую передачу сообщений, но порты не нужны, imo 🙂
Ответ №1:
Как правило, вы можете добавить порт к своему объекту или даже создать пользовательский тип порта, как описано здесь. Однако для отправки сообщения в / из портов сообщение должно расширять агент, а порты должны быть подключены через соединитель. Шаблон реализации:
- Внутри агента отправителя: иметь блок ввода, подключенный к порту
- Внутренний агент приемника: иметь порт, подключенный к выходному блоку
- в главном агенте: подключите порт отправителя к порту получателя
- Внутри отправителя: создайте
msg
агент и используйтеenter.take(msg)
- Будет выполнено вышеописанное: Ввод -> Порт отправителя -> Порт получателя -> Выход
- Выполните какое-либо действие в
on Exit
свойстве блока выхода в приемнике
Комментарии:
1. Я создал агент «Msg» со всеми параметрами, которые я хочу отправить. Я настроил как получателя, так и отправителя, как вы сказали. В оба блока я поместил агент «msg», который я буду использовать в качестве временной переменной, и я настроил оба блока ввода и выхода для работы с типом агента «Msg». Я понял это с помощью enter.take (msg) Я смогу отправить свою переменную, но как получить ее из блока выхода? Что касается пункта 6, есть ли что-то вроде exit.get(msg)? Напишу ли я это что-то в обратном вызове OnExit в блоке exit, выполню ли я код, как только что-то выйдет? Большое спасибо!
2. Посмотрите на документы Exit , в основном, есть
On exit
действие сagent
параметром. В этом случае этоagent
будет сообщение, отправленное вами черезenter.take(msg)
call.3. Большое спасибо, @Artem. Мне удалось это сделать! Я хочу задать вам последний дополнительный вопрос: я пытался подключить оба
enter
exit
блока and к одному и тому же порту, но Anylogic выдает мне сообщение об ошибке, сообщая, что одинOutPort
может быть подключен только к anInPort
. По вашему опыту, возможно ли отправлять и получать агента через один порт? Тем не менее, большое спасибо!4. К сожалению, использование одного и того же порта для входа и выхода невозможно. Маленький секрет AnyLogic в том, что порты — это просто визуальная разметка, в фоновом режиме она эффективно соединяет ввод с выходом , пропуская все порты. Следовательно, точно так же, как вы не можете подключить Enter к Enter , вы не можете использовать один порт как
InPort
иOutPort
.
Ответ №2:
Я, наконец, понял, как сделать то, что я имел в виду. Порты способны как отправлять, так и получать данные только с одним соединителем. Больше никаких последующих блоков не требуется, как предложил @Artem, но его ответ дал мне правильное предложение найти собственное решение.
Когда порты обмениваются сообщениями между собой, когда они получают его, они называют его «msg»; поэтому «msg» может быть передан функциям или может использоваться для обращения к внутренним полям (например: msg.custom_field).
Чтобы максимально использовать порты, необходимо обеспечить детализацию использования на низком уровне, включив режим разработчика. Для этого следуйте инструкциям: Инструмент -> Настройки -> Разработка -> Режим разработчика библиотеки. Выбрав этот голос, теперь при нажатии на порты появляются эти новые голоса:
Порты теперь можно настроить с типом сообщения «вход» и «выход» (при необходимости они могут быть также разными), и можно связать функцию обратного вызова, когда порт получает или отправляет сообщение. Например, на рисунке 1 я установил функцию «doSomething», которая принимает класс полученного сообщения и что-то с ним делает.
Для отправки сообщения следует использовать код «port.send (something)», и функция OnSend будет учтена перед отправкой.
Также возможно создавать пользовательские порты, наследующие тип класса порта, но я не стал так глубоко загонять себя в белую кроличью нору, извините.
На рисунке 2 показан небольшой тестовый стенд, который я создал с (рабочими) портами. Я надеюсь, что это небольшое руководство может помочь вам всем, ребята, даже если этот вид использования предназначен только для очень специфических нужд.