Альтернативное использование портов Anylogic (?)

#anylogic

Вопрос:

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

Пример агента

Поскольку у меня много информации для обмена, я создал одну переменную для ввода и одну для вывода, используя опцию «Массив» и используя правильные размеры. Мне было интересно, могу ли я сделать их более чистыми и иметь лучшую функциональность, используя порты. Я видел, как они подключались к уже существующим библиотечным компонентам, но никогда в агенте, созданном с нуля. В документации я прочитал, что я мог бы использовать команды «port.send (obj)» и «port.receive (obj)», но я ничего не мог сделать. Итак, мой вопрос: можно ли использовать порты для отправки объектов через код (возможно, агенты, динамическую переменную или что-то еще) между агентами? Если да, то как запустить действие приема в целевом агенте? Заранее большое спасибо! P

Комментарии:

1. Я рекомендую использовать соединения Agent link для передачи сообщений, если вы находитесь на уровне от начального до среднего. После этого используйте пользовательскую передачу сообщений, но порты не нужны, imo 🙂

Ответ №1:

Как правило, вы можете добавить порт к своему объекту или даже создать пользовательский тип порта, как описано здесь. Однако для отправки сообщения в / из портов сообщение должно расширять агент, а порты должны быть подключены через соединитель. Шаблон реализации:

  1. Внутри агента отправителя: иметь блок ввода, подключенный к порту
  2. Внутренний агент приемника: иметь порт, подключенный к выходному блоку
  3. в главном агенте: подключите порт отправителя к порту получателя
  4. Внутри отправителя: создайте msg агент и используйте enter.take(msg)
  5. Будет выполнено вышеописанное: Ввод -> Порт отправителя -> Порт получателя -> Выход
  6. Выполните какое-либо действие в 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 может быть подключен только к an InPort . По вашему опыту, возможно ли отправлять и получать агента через один порт? Тем не менее, большое спасибо!

4. К сожалению, использование одного и того же порта для входа и выхода невозможно. Маленький секрет AnyLogic в том, что порты — это просто визуальная разметка, в фоновом режиме она эффективно соединяет ввод с выходом , пропуская все порты. Следовательно, точно так же, как вы не можете подключить Enter к Enter , вы не можете использовать один порт как InPort и OutPort .

Ответ №2:

Я, наконец, понял, как сделать то, что я имел в виду. Порты способны как отправлять, так и получать данные только с одним соединителем. Больше никаких последующих блоков не требуется, как предложил @Artem, но его ответ дал мне правильное предложение найти собственное решение.

Когда порты обмениваются сообщениями между собой, когда они получают его, они называют его «msg»; поэтому «msg» может быть передан функциям или может использоваться для обращения к внутренним полям (например: msg.custom_field).

Чтобы максимально использовать порты, необходимо обеспечить детализацию использования на низком уровне, включив режим разработчика. Для этого следуйте инструкциям: Инструмент -> Настройки -> Разработка -> Режим разработчика библиотеки. Выбрав этот голос, теперь при нажатии на порты появляются эти новые голоса:

меню разработчика портов

Порты теперь можно настроить с типом сообщения «вход» и «выход» (при необходимости они могут быть также разными), и можно связать функцию обратного вызова, когда порт получает или отправляет сообщение. Например, на рисунке 1 я установил функцию «doSomething», которая принимает класс полученного сообщения и что-то с ним делает.

Для отправки сообщения следует использовать код «port.send (something)», и функция OnSend будет учтена перед отправкой.

Также возможно создавать пользовательские порты, наследующие тип класса порта, но я не стал так глубоко загонять себя в белую кроличью нору, извините.

Блоки, соединенные портами

На рисунке 2 показан небольшой тестовый стенд, который я создал с (рабочими) портами. Я надеюсь, что это небольшое руководство может помочь вам всем, ребята, даже если этот вид использования предназначен только для очень специфических нужд.