diff --git a/doc/source/_static/transmission_growing.png b/doc/source/_static/transmission_growing.png new file mode 100644 index 0000000..fd7c8bf Binary files /dev/null and b/doc/source/_static/transmission_growing.png differ diff --git a/doc/source/_static/transmission_starting.png b/doc/source/_static/transmission_starting.png new file mode 100644 index 0000000..74841aa Binary files /dev/null and b/doc/source/_static/transmission_starting.png differ diff --git a/doc/source/nodes.rst b/doc/source/nodes.rst index 1311428..90e44b0 100644 --- a/doc/source/nodes.rst +++ b/doc/source/nodes.rst @@ -312,6 +312,36 @@ and will always be written. Unlike :ref:`orchestrator-mobility-polling`, this location tracing may not be disabled. + +Transmission Animations +^^^^^^^^^^^^^^^^^^^^^^^ + +To visualize wireless transmissions, the ``NodeConfiguration`` class provides the ``Transmit()`` +method. The signature for this method is below: + +.. cpp:function:: void NodeConfiguration::Transmit (Time duration, double targetSize, Color3 color = GRAY_30) + + +When called, this displays an expanding sphere in the application. The sphere will expand for ``duration`` +and grow to ``targetSize``. Optionally, the color of the sphere may be specified (default gray). + +Only one ongoing transmission is allowed per ``Node``. If another transmission is started before +the previous one has been completed, the animation will stop for the previous transmission, +and the new transmission's animation will play. + +.. figure:: _static/transmission_starting.png + :alt: Transmission Starting + :scale: 50 + + Transmission bubble starting + +.. figure:: _static/transmission_growing.png + :alt: Transmission Starting + :scale: 50 + + A transmission in progress + + Attributes ^^^^^^^^^^ diff --git a/model/event-message.h b/model/event-message.h index 71a9698..0e1c857 100644 --- a/model/event-message.h +++ b/model/event-message.h @@ -39,6 +39,7 @@ #include #include #include +#include #include namespace ns3::netsimulyzer { @@ -50,6 +51,15 @@ struct CourseChangeEvent Vector position; }; +struct TransmitEvent +{ + Time time; + uint32_t nodeId; + Time duration; + double targetSize; + Color3 color; +}; + struct NodeOrientationChangeEvent { Time time; diff --git a/model/node-configuration.cc b/model/node-configuration.cc index 6821394..fbcae92 100644 --- a/model/node-configuration.cc +++ b/model/node-configuration.cc @@ -193,6 +193,39 @@ NodeConfiguration::CourseChange (ns3::Ptr model) m_orchestrator->HandleCourseChange (event); } +void +NodeConfiguration::Transmit (Time duration, double targetSize, Color3 color) +{ + NS_LOG_FUNCTION (this << duration << targetSize); + + // If we haven't been aggregated with a Node yet. + // Assume we're still setting up + const auto node = GetObject (); + if (!node) + { + NS_LOG_DEBUG ("Not triggering NodeTransmit event. No Node aggregated"); + return; + } + + TransmitEvent event; + event.time = Simulator::Now (); + event.nodeId = node->GetId (); + event.duration = duration; + event.targetSize = targetSize; + event.color = color; + + if (lastTransmissionEnd > event.time + event.duration) + { + NS_LOG_WARN ("Node ID: " + std::to_string (event.nodeId) + + " transmission event interrupted. " + "Expected end: " + + std::to_string (lastTransmissionEnd.GetMilliSeconds ()) + "ms " + + "Current time: " + std::to_string (event.time.GetMilliSeconds ()) + "ms"); + } + + m_orchestrator->HandleTransmit (event); +} + std::optional NodeConfiguration::MobilityPoll (void) { diff --git a/model/node-configuration.h b/model/node-configuration.h index edeb090..c26da82 100644 --- a/model/node-configuration.h +++ b/model/node-configuration.h @@ -93,6 +93,33 @@ class NodeConfiguration : public Object */ void CourseChange (Ptr model); + /** + * Triggers in the application, + * a bubble to grow out of the center + * of the Node, which expands for + * `duration` and until it reaches `targetSize`. + * To visually indicate a transmission of + * some sort has occurred. + * + * \warning Only one transmission per node + * may be occurring at once. If another transmission + * is triggered while one is still ongoing, + * the ongoing transmission will be cut off, and + * the new one will begin. + * + * \param duration + * How long the transmission bubble + * grows. + * + * \param targetSize + * What size the bubble should be + * when `duration` has passed + * + * \param color + * What color to draw the transmission bubble + */ + void Transmit(Time duration, double targetSize, Color3 color = GRAY_30); + /** * Called by the Orchestrator during a mobility poll. * @@ -322,6 +349,12 @@ class NodeConfiguration : public Object * Flag tracking if we've connected the CourseChanged callback to a MobilityModel */ bool m_attachedMobilityTrace = false; + + /** + * Time the last transmission event was supposed to end. + * Used for logging warnings about truncated transmissions + */ + Time lastTransmissionEnd{Seconds (-1.0)}; }; } // namespace ns3::netsimulyzer diff --git a/model/orchestrator.cc b/model/orchestrator.cc index 12428b6..8374c52 100644 --- a/model/orchestrator.cc +++ b/model/orchestrator.cc @@ -840,6 +840,28 @@ Orchestrator::HandleColorChange (const NodeColorChangeEvent &event) m_document["events"].emplace_back (element); } +void +Orchestrator::HandleTransmit (const TransmitEvent &event) +{ + NS_LOG_FUNCTION (this); + + if (Simulator::Now () < m_startTime || Simulator::Now () > m_stopTime) + { + NS_LOG_DEBUG ("HandleTransmit() Activated outside (StartTime, StopTime), Ignoring"); + return; + } + + nlohmann::json element; + element["type"] = "node-transmit"; + element["milliseconds"] = event.time.GetMilliSeconds (); + element["id"] = event.nodeId; + element["duration"] = event.duration.GetMilliSeconds(); + element["target-size"] = event.targetSize; + element["color"] = colorToObject (event.color); + + m_document["events"].emplace_back (element); +} + uint32_t Orchestrator::Register (Ptr decoration) { diff --git a/model/orchestrator.h b/model/orchestrator.h index b177f22..696d686 100644 --- a/model/orchestrator.h +++ b/model/orchestrator.h @@ -170,6 +170,17 @@ class Orchestrator : public ns3::Object */ void HandleColorChange (const NodeColorChangeEvent &event); + /** + * Trace sink for when a Node has indicated it's transmitting. + * + * Prefer to use `NodeConfiguration::Transmit`, instead + * of calling this directly. + * + * \param event The event info for the transmit event + * \see NodeConfiguration::Transmit + */ + void HandleTransmit (const TransmitEvent &event); + /** * \brief Flag a Decoration to be tracked. *