How do I block NS-3?

141 views
Skip to first unread message

琳琅

unread,
Apr 10, 2023, 7:52:11 AM4/10/23
to ns-3-users
How do I block NS-3?

I'm sorry to bother you. Now I have a problem again. I want to co-simulate ns-3 with another simulation software sumo, and I have difficulty in time synchronization.

As we know, NS-3 is a discrete event simulator. If the total simulation time is 100s and I only add one event in the 50s, then the middle 1-50s will be skipped directly. I want to suspend the operation of NS-3 after the execution of the event in the 50s, and then continue to run NS-3 again when appropriate.

May I ask how to achieve the above requirements? Thank you very much for your help!

Tommaso Pecorella

unread,
Apr 10, 2023, 10:18:43 AM4/10/23
to ns-3-users
Good question. You don't (but there's a catch).

Now I'm going technical, so brace yourself.

In order to do what you're asking you need some stuff that is not doable with ns-3 out-of-the-box. But it can be done.

First and foremost you must decide how to communicate with the ns-3 simulation. An ns-3 simulation can be either a program (if made entirely with C++) or a script in Python. The two alternatives are slightly different with what I'll say in the following, with the Python alternative being slightly simpler to implement.

Let's start with the beginning. The classes responsible for scheduling events and advancing time are the child classes of SimulatorImpl (there are many actually). As they are, they do consume events one after the other, without checking anything.
What you need is a new SimulatorImpl class (or a child of an existing one) that can:
  1. Receive a signal, or something, telling it to advance "until time x is reached".
  2. Receive a signal, or something, telling it to continue the execution "until time x is reached".
Note: basically the two are the same. But you can also have a variation like "execute exactly one event", and "execute one event and all the events with the same time", to advance the execution by one event and one "time step".

Just as a reference, check the following function:
oid
DefaultSimulatorImpl::Run()
{
NS_LOG_FUNCTION(this);
// Set the current threadId as the main threadId
m_mainThreadId = std::this_thread::get_id();
ProcessEventsWithContext();
m_stop = false;

while (!m_events->IsEmpty() && !m_stop)
{
ProcessOneEvent();
}

// If the simulator stopped naturally by lack of events, make a
// consistency test to check that we didn't lose any events along the way.
NS_ASSERT(!m_events->IsEmpty() || m_unscheduledEvents == 0);
}

Now, what happens if you set m_stop ? (it is set by calling Simulator::Stop()
Well, the simulation stops.

Can you call Simulator::Run() again? Yes, of course. The problem is calling Simulator::Stop() at the right time. Well, easy... call Simulator::Stop(const Time& delay) before the simulation starts.
This is all good if you know ahead when you want to stop the simulation (and then start again, maybe).

If you need to do it *while* the simulation runs, things gets messy, but you can do it by defining a new SimulatorImpl and adding your own methods.

Now, why did I say that Python and C++ are different? So far they aren't - but with C++ you'll need a way to signal the program (interrupts, RPCs, sockets, etc), while with Python you'll have (maybe) an easier time. Don't underestimate how you'll communicate with your script.

Said so, there's no "out of the box" way, but it's something that is definitely now dramatic to do. Just get your favourite IDE and start developing.

琳琅

unread,
Apr 11, 2023, 2:50:28 AM4/11/23
to ns-3-users

Thank you. This seems to be a very effective method. Thanks again for your help !
Reply all
Reply to author
Forward
0 new messages