The Real-Time Simulation Protocol
by Jim Ledin


Listing One
// Distributed Simulation Message Definition
// Declare names for all federates:
federate CommandGenerator, Controller, Plant;

// Define messages. The federate named with each message is the sender.
message CommandGenerator.Update
{
    double command;
};
message Controller.Update
{
    double drive;
};
message Plant.Update
{
    double output;
};
// Subscription list. Each federate can subscribe to (i.e., receive) any
// message including ones it produces.

// The Controller gets updates from the CommandGenerator and Plant
subscribe Controller : CommandGenerator.Update, Plant.Update;

// The Plant gets updates from the Controller
subscribe Plant : Controller.Update;


Listing Two
C:\Projects\DistSim>translator DistSim.mdf
Generating CommandGeneratorSend.h
Generating ControllerSend.h
Generating ControllerRcv.h
Generating PlantSend.h
Generating PlantRcv.h
Generating _MsgData.cpp

C:\Projects\DistSim>

Listing Three
// CommandGeneratorSend class
// Generated Thu Aug 24 13:33:36 2000 from distsim.mdf
// *** This file was automatically generated. Do not edit it! ***
#include <RTSP.h>
#include <RTSP_Internals.h>
class CommandGeneratorSend
{
public:
    struct Update
    {
        double command;
        uint _TimeTag;
        ushort _SequenceNum;
        uchar _ReceiverIndex;
        uchar _SenderIndex;
        bool Send(RTSP& rtsp, uchar rcv_index = _AllIndexes)
            { return _SendMessage(rtsp, this, 0, rcv_index); }
    };
};


Listing Four
#include <RTSP.h>
#include <stdio.h>
#include "CommandGeneratorSend.h"

RTSP* rtsp;

CommandGeneratorSend::Update command_update;

bool ping_callback()
{
    printf("Ping callback\n");
    return true;
}
bool init_callback()
{
    printf("Initialize callback\n");
    return true;
}
bool start_callback()
{
    printf("Start callback\n");
    return true;
}
bool end_run = false;
bool halt_callback()
{
    printf("Halt callback\n");
    end_run = true;
    return true;
}
int main()
{
    printf("CommandGenerator Federate\n");
    printf("Jim Ledin    August, 2000\n\n");

    // Determine the number of frames per second
    int frames_per_sec = 100;
    printf("\nUpdate rate: %d frames/sec\n\n", frames_per_sec);

    rtsp = new RTSP("CommandGenerator", 0);
    rtsp->SetPingCallback(ping_callback);
    rtsp->SetInitializeCallback(init_callback);
    rtsp->SetStartCallback(start_callback);
    rtsp->SetHaltCallback(halt_callback);

    for (;;)
    {
        end_run = false;
        printf("Waiting for Initialize\n");
        rtsp->WaitForInit();

        printf("Waiting for Start\n");
        rtsp->WaitForStart();
        printf("Running\n");

        double step_time = 1.0 / frames_per_sec;

        rtsp->StartTimer();
        uint frame = 0;
        while (!end_run)
        {
            // Time since start of run
            double Time = frame * step_time;

            // Output a new random command every 10 seconds
            if (frame % (10*frames_per_sec) == 0)
            {
                double command = 10.0 * double(rand()) / RAND_MAX;
                command_update.command = command;
                command_update.Send(*rtsp);

                printf("Time: %.1lf; New command: %.3lf\n", Time, command);
                fflush(stdout);
            }
            uint end_of_frame = uint(1e6 * ++frame * step_time);
            uint cur_time = rtsp->ReadTimer();
            while (cur_time < end_of_frame)
            {
                rtsp->PollRcv(true, end_of_frame - cur_time);
                cur_time = rtsp->ReadTimer();
            }
        }
        printf("End of run\n");
    }
    return 0;
}


Listing Five
start controller DistSim.mdf
start CommandGenerator
start Controller
start Plant




3


