-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathDynSimStep.cpp
More file actions
144 lines (124 loc) · 5.11 KB
/
DynSimStep.cpp
File metadata and controls
144 lines (124 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// SPDX-FileCopyrightText: 2024 Vector Informatik GmbH
//
// SPDX-License-Identifier: MIT
#include <iostream>
#include <random>
#include <thread>
#include "silkit/SilKit.hpp"
using namespace std::chrono_literals;
std::ostream& operator<<(std::ostream& out, std::chrono::nanoseconds timestamp)
{
out << std::chrono::duration_cast<std::chrono::milliseconds>(timestamp).count() << "ms";
return out;
}
int main(int argc, char** argv)
{
if (argc != 5 && argc != 6)
{
std::cerr << "Wrong number of arguments! Start demo with: " << argv[0] <<
" <ParticipantName> "
"<StepSize> "
"[-A (Autonomous) | -C (Coordinated)] "
"[-M (ByMinimalDuration) | -D (ByOwnDuration)] "
"[-R (Optional; Randomize StepSize (1ms to 10ms) with 10% probability every step)]" << std::endl;
return -1;
}
// Arg 1: Participant Name
std::string participantName(argv[1]);
// Arg 2: Step Size
auto stepSize = std::chrono::milliseconds(std::stoi(argv[2]));
std::cout << "Starting with stepSize=" << stepSize << std::endl;
// Arg 3: Operation Mode
auto operationMode = SilKit::Services::Orchestration::OperationMode::Coordinated;
if (std::string(argv[3]) == "-A")
{
std::cout << "Using OperationMode::Autonomous" << std::endl;
operationMode = SilKit::Services::Orchestration::OperationMode::Autonomous;
}
else if (std::string(argv[3]) == "-C")
{
std::cout << "Using OperationMode::Coordinated" << std::endl;
}
else
{
std::cerr << "Unknown third argument '" << argv[3] << "'. Did you mean '-A' for autonomous mode or '-C' for coordinated mode?" << std::endl;
return -1;
}
// Arg 4: Time Advance Mode
auto timeAdvanceMode = SilKit::Services::Orchestration::TimeAdvanceMode::ByMinimalDuration;
if (std::string(argv[4]) == "-M")
{
std::cout << "Using TimeAdvanceMode::ByMinimalDuration" << std::endl;
}
else if (std::string(argv[4]) == "-D")
{
timeAdvanceMode = SilKit::Services::Orchestration::TimeAdvanceMode::ByOwnDuration;
std::cout << "Using TimeAdvanceMode::ByOwnDuration" << std::endl;
}
else
{
std::cerr << "Unknown argument '" << argv[4]
<< "'. Did you mean '-M' for TimeAdvanceMode::ByMinimalDuration or '-D' for TimeAdvanceMode::ByOwnDuration?" << std::endl;
return -1;
}
// Arg 5: Optional Randomize Step Size
bool randomizeStepSize = false;
if (argc == 6)
{
if (std::string(argv[5]) == "-R")
{
randomizeStepSize = true;
std::cout << "Randomizing step size every 10 steps." << std::endl << std::endl;
}
else
{
std::cerr << "Unknown argument '" << argv[5] << "'. Did you mean '-R' to randomize the step size every 10 steps?" << std::endl;
return -1;
}
}
try
{
// Setup participant, lifecycle, time synchronization and logging.
const std::string registryUri = "silkit://localhost:8500";
const std::string configString = R"({"Logging":{"Sinks":[{"Type":"Stdout","Level":"Info"}]}})";
auto participantConfiguration = SilKit::Config::ParticipantConfigurationFromString(configString);
auto participant = SilKit::CreateParticipant(participantConfiguration, participantName, registryUri);
auto logger = participant->GetLogger();
auto* lifecycleService = participant->CreateLifecycleService({operationMode});
auto* timeSyncService = lifecycleService->CreateTimeSyncService(timeAdvanceMode);
std::random_device rd;
std::mt19937 rng(rd());
auto bounded_rand = [&rng](unsigned range) {
std::uniform_int_distribution<unsigned> dist(1, range);
return dist(rng);
};
timeSyncService->SetSimulationStepHandler(
[randomizeStepSize, logger, timeSyncService, participantName, bounded_rand](
std::chrono::nanoseconds now,
std::chrono::nanoseconds duration) {
// The invocation of this handler marks the beginning of a simulation step.
{
std::stringstream ss;
ss << "--------- Simulation step T=" << now << ", duration=" << duration << " ---------";
logger->Info(ss.str());
}
if (randomizeStepSize && bounded_rand(10) == 1)
{
auto rndStepDuration = bounded_rand(10);
timeSyncService->SetStepDuration(std::chrono::milliseconds(rndStepDuration));
std::stringstream ss;
ss << "--------- Changing step size to " << rndStepDuration << "ms ---------";
logger->Info(ss.str());
}
std::this_thread::sleep_for(500ms);
}, stepSize);
auto finalStateFuture = lifecycleService->StartLifecycle();
finalStateFuture.get();
}
catch (const std::exception& error)
{
std::cerr << "Something went wrong: " << error.what() << std::endl;
return -2;
}
return 0;
}