ModelSpace
All Classes Namespaces Functions Variables Enumerations Pages
Tasks.h
1/******************************************************************************
2* Copyright (c) ATTX LLC 2024. All Rights Reserved.
3*
4* This software and associated documentation (the "Software") are the
5* proprietary and confidential information of ATTX, LLC. The Software is
6* furnished under a license agreement between ATTX and the user organization
7* and may be used or copied only in accordance with the terms of the agreement.
8* Refer to 'license/attx_license.adoc' for standard license terms.
9*
10* EXPORT CONTROL NOTICE: THIS SOFTWARE MAY INCLUDE CONTENT CONTROLLED UNDER THE
11* INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) OR THE EXPORT ADMINISTRATION
12* REGULATIONS (EAR99). No part of the Software may be used, reproduced, or
13* transmitted in any form or by any means, for any purpose, without the express
14* written permission of ATTX, LLC.
15******************************************************************************/
16/*
17Tasks header file - Includes definitions for task, model, monitor, event, construct
18
19Author: Alex Reynolds
20*/
21#ifndef ARCHITECTURE_TASKS_H
22#define ARCHITECTURE_TASKS_H
23
24#include "architecture/EventLogger.h"
25#include "architecture/Time.h"
26#include "data_management/GraphTreeObject.h"
27#include "data_management/DataIO.hpp"
28#include "core/clockwerkerrors.h"
29#include "core/macros.h"
30
31namespace clockwerk {
32
33 /// Classes the Task object will rely on
34 class Executive;
35
36 /// @brief This is the base implementation of the task class
37 ///
38 /// This class defines the base task from which other tasks
39 /// are inherited. Tasks are simple events which execute
40 /// every step, or as scheduled, with their step function.
41 ///
42 /// The task class has two key step functions called by the
43 /// Scheduler class -- startup, which should be called once
44 /// on step start, and the step function, which is called every
45 /// time the event may step. These functions should not be
46 /// implemented in derived classes. Instead, derived events
47 /// should implement the start and execute functions,
48 /// which are designed for that purpose. The eventStartup
49 /// is called from within startup, and should implement event-
50 /// specific setup functionality. The execute function will
51 /// be called every step step, and should
52 /// contain all event-specific code.
53 ///
54 /// The task class has parameters, inputs, and outputs which correspond to
55 /// the following definitions:
56 ///
57 /// PARAMETERS: Configuration flags which should be carefully controlled
58 /// and only modified at few, select events (i.e. not every
59 /// timestep)
60 /// INPUTS: Input parameters to the model which may, but do not have
61 /// to, change often. These will often be connected to the
62 /// outputs of other models.
63 /// OUTPUTS: Output parameters from the model which are the result
64 /// of an internal calculation in the model.
65 ///
66 /// This class should not be used on its own, and must be
67 /// derived in a child class.
68 class Task : public GraphTreeObject {
69 public:
70 /// @brief Default constructor for the task object for simplicity.
71 /// Note: Masks some functionality and should not be used for
72 /// production deployment.
73 Task();
74
75 /// @brief Task-based constructor for the task. Auto-assigns executive
76 /// @param pnt The task to assign as parent of this task
77 /// @param nme Name of the task
78 Task(Task &pnt, const std::string &m_name="Unnamed");
79
80 /// @brief Executive-based constructor for the task
81 /// @param executive The executive to set
82 /// @param m_name The name for the task
83 Task(Executive &executive, const std::string &m_name="Unnamed");
84
85 /// @brief Task-based constructor for the task. Auto-assigns executive
86 /// @param pnt The task to assign as parent of this task
87 /// @param nme Name of the task
88 /// @param slot The slot to which the task should be scheduled.
89 /// Negative indicates it should not be scheduled.
90 Task(Task &pnt, int slot, const std::string &m_name="Unnamed");
91
92 /// @brief Executive-based constructor for the task
93 /// @param executive The executive to set
94 /// @param m_name The name for the task
95 /// @param slot The slot to which the task should be scheduled.
96 /// Negative indicates it should not be scheduled.
97 Task(Executive &executive, int slot, const std::string &m_name="Unnamed");
98
99 /// @brief Desrtuctor. Doesn't really do anything
100 virtual ~Task() {};
101
102 /// @brief Function to perform startup activities (step once at start after creation).
103 /// Should not be modified in derived task.
104 /// @return Error code corresponding to success/failure
105 /// @note This is the master task function, which calls start internally
106 /// and performs other tasks before and after
107 int startup();
108
109 /// @brief Function to step the task. This will be called every step
110 /// @return Error code corresponding to success/failure
111 /// @note Inherited in derived monitor/event for special cases but
112 /// should not be implemented directly in inherited classes
113 virtual int step();
114
115 /// @brief Function to activate the task
116 /// @return Error code corresponding to success/failure
117 /// @note This is an inherited function that should be overwritten in inherited
118 /// task class, if implemented. If it is not implemented in the inherited
119 /// class, step() function will do nothing
120 virtual int activate() {active(true); _error = step(); return _error;}
121
122 /// @brief Function to deactivate the task
123 /// @return Error code corresponding to success/failure
124 /// @note This is an inherited function that should be overwritten in inherited
125 /// task class, if implemented. If it is not implemented in the inherited
126 /// class, step() function will do nothing
127 virtual int deactivate() {active(false); return NO_ERROR;}
128
129 /// @brief Function to command this task to record timing information
130 void recordTiming() {_record_timing = true;}
131
132 /// @brief Function to set the local model log level
133 /// @param new_level The new level to set logging to
134 void logLevel(log_level_e new_level) {_local_log_level = new_level;}
135
136 /// @brief The active flag for the task -- set to true by default
137 DataIO<bool> active = DataIO<bool>(this, "active", true);
138
139 /// @brief The schedule slot this task will step in -- set to 0 by default
140 DataIO<int> schedule_slot = DataIO<int>(this, "schedule_slot", 0);
141
142 /// @brief Time of entry (per wallClockTimer) of the last step of this task
143 DataIO<Time> entry_time = DataIO<Time>(this, "entry_time", Time());
144
145 /// @brief Time of exit (per wallClockTimer) of the last step of this task
146 DataIO<Time> exit_time = DataIO<Time>(this, "exit_time", Time());
147 protected:
148 /// @brief Function to perform task startup activities (step once after creation)
149 /// @return Error code corresponding to success/failure
150 /// @note This is an inherited function that should be overwritten in inherited
151 /// task class, if implemented. If it is not implemented in the inherited
152 /// class, it will do nothing.
153 virtual int start() {return NO_ERROR;}
154
155 /// @brief Function to execute the task. All math and calculations should be here.
156 /// @return Error code corresponding to success/failure
157 /// @note This is an inherited function that should be overwritten in inherited
158 /// task class, if implemented. If it is not implemented in the inherited
159 /// class, it will do nothing.
160 virtual int execute() {return NO_ERROR;}
161
162 /// ----------------------------------------------------------
163 /// General utility functions for models
164 /// ----------------------------------------------------------
165 /// @brief Overloaded function to check range on a parameter
166 /// @param min The minimum acceptable value
167 /// @param max The maximum acceptable value
168 /// @param signal The signal to be evaluated
169 /// @return Error code corresponding to value validity
170 int rangeCheck(double min, double max, DataIO<double> signal);
171 int rangeCheck(float min, float max, DataIO<float> signal);
172 int rangeCheck(int min, int max, DataIO<int> signal);
173
174 /// Our local log level -- allows a higher log level locally than the overall system
175 log_level_e _local_log_level = NONE;
176
177 /// Simple variable to track error in task
178 int _error = NO_ERROR;
179
180 /// Variable to enable or disable timing
181 bool _record_timing = false;
182
183 /// Pointer to the executive object
184 Executive *exc = nullptr;
185 };
186
187 /// @brief Base class implementation of the monitor
188 ///
189 /// This file implements the base monitor class. A monitor is
190 /// a simplified model that checks one or multiple conditions
191 /// and sets a flag when triggered. It is designed to be
192 /// implemented in a child class which sets the monitor flag.
193 ///
194 /// Child classes should simply implement the "checkConditions"
195 /// virtual class, which sets the trigger flag.
196 ///
197 /// By default, the monitor comes with two flags which the child
198 /// implementation should set:
199 ///
200 /// trigger - This is the flag indicating when the monitor's conditions
201 /// are met. It will indicate true when conditions are met
202 /// (either once or thereafter depending on persistence flag)
203 /// persistence - This flag indicates whether the monitor should persist
204 /// upon trigger or not. If set to true, once monitor conditions
205 /// are met the monitor will cease stepning and remain true
206 /// thereafter. If false, the monitor may set the trigger on/
207 /// off at its own discretion.
208 ///
209 /// Note that monitors are analogous to interrupts -- they should do
210 /// nothing besides check conditions and set their own flag. Any
211 /// resulting actions should be taken by a triggered event.
212 class Monitor : public Task {
213 public:
214 /// @brief Default constructor for the task object for simplicity.
215 /// Note: Masks some functionality and should not be used for
216 /// production deployment.
217 Monitor() : Task() {};
218
219 /// @brief Task-based constructor for the task. Auto-assigns executive
220 /// @param pnt The task to assign as parent of this task
221 /// @param nme Name of the task
222 /// @param schedule_slot The slot to which the task should be scheduled.
223 /// Negative indicates it should not be scheduled.
224 Monitor(Task &pnt, int schedule_slot=0, const std::string &m_name="Unnamed")
225 : Task(pnt, schedule_slot, m_name) {};
226
227 /// @brief Executive-based constructor for the task
228 /// @param executive The executive to set
229 /// @param m_name The name for the task
230 /// @param schedule_slot The slot to which the task should be scheduled.
231 /// Negative indicates it should not be scheduled.
232 Monitor(Executive &executive, int schedule_slot=0, const std::string &m_name="Unnamed")
233 : Task(executive, schedule_slot, m_name) {};
234
235 /// @brief Desrtuctor. Doesn't really do anything
236 virtual ~Monitor() {};
237
238 /// @brief Function to step the monitor. This will be called every step
239 /// @return Error code corresponding to success/failure
240 int step();
241
242 /// @brief Function to reset the monitor's trigger to false
243 void reset() {trigger(false);}
244
245 /// Our trigger -- this is the flag set and unset by the monitor as
246 /// its ultimate output, and should be used downstream by events, etc.
247 DataIO<bool> trigger = DataIO<bool>(this, "trigger", false);
248
249 /// Our latch flag -- If true, the monitor will continue to return
250 /// triggered even after conditions change.
251 DataIO<bool> latch = DataIO<bool>(this, "latch", false);
252 };
253
254 /**
255 * @brief Base event class
256 *
257 * The event class is a special class implementation designed
258 * to step only when triggered by an external flag, typically
259 * tied to the Monitor class.
260 *
261 * The event class has two key step functions called by the
262 * Scheduler class -- startup, which should be called once
263 * on step start, and the step function, which is called every
264 * time the event may step. These functions should not be
265 * implemented in derived classes. Instead, derived events
266 * should implement the eventStartup and execute functions,
267 * which are designed for that purpose. The eventStartup
268 * is called from within startup, and should implement event-
269 * specific setup functionality. The execute function will
270 * be called only when the event is triggered, and should
271 * contain all event-specific code.
272 *
273 * Events are triggered according to the trigger() signal
274 * included in this class definition. It should be mapped
275 * to a boolean indicator of trigger, which should almost
276 * definitely/always be the trigger on a monitor.
277 */
278 class Event : public Task {
279 public:
280 /// @brief Default constructor for the task object for simplicity.
281 /// Note: Masks some functionality and should not be used for
282 /// production deployment.
283 Event() : Task() {};
284
285 /// @brief Task-based constructor for the task. Auto-assigns executive
286 /// @param pnt The task to assign as parent of this task
287 /// @param nme Name of the task
288 /// @param schedule_slot The slot to which the task should be scheduled.
289 /// Negative indicates it should not be scheduled.
290 Event(Task &pnt, int schedule_slot=0, const std::string &m_name="Unnamed")
291 : Task(pnt, schedule_slot, m_name) {};
292
293 /// @brief Executive-based constructor for the task
294 /// @param executive The executive to set
295 /// @param m_name The name for the task
296 /// @param schedule_slot The slot to which the task should be scheduled.
297 /// Negative indicates it should not be scheduled.
298 Event(Executive &executive, int schedule_slot=0, const std::string &m_name="Unnamed")
299 : Task(executive, schedule_slot, m_name) {};
300
301 /// @brief Desrtuctor. Doesn't really do anything
302 virtual ~Event() {};
303
304 /// @brief Function to step the Event. This will be called every step,
305 /// but only call execute when triggered
306 /// @return Error code corresponding to success/failure
307 int step();
308
309 /// Our trigger -- this is the flag indicating to the event that it
310 /// should step.
311 DataIO<bool> trigger = DataIO<bool>(this, "trigger", false);
312 };
313
314}
315
316#endif
Class for inter-object communication.
Definition DataIO.hpp:46
DataIO(GraphTreeObject *data_parent, std::string data_name, T initial_value)
Constructor for the DataIO object.
Definition DataIO.hpp:134
int operator()(const T &new_value)
Function to set the value of the DataIO object.
Definition DataIO.hpp:115
Base event class.
Definition Tasks.h:278
DataIO< bool > trigger
Our trigger – this is the flag indicating to the event that it should step.
Definition Tasks.h:311
Event()
Default constructor for the task object for simplicity. Note: Masks some functionality and should not...
Definition Tasks.h:283
Event(Task &pnt, int schedule_slot=0, const std::string &m_name="Unnamed")
Task-based constructor for the task. Auto-assigns executive.
Definition Tasks.h:290
virtual ~Event()
Desrtuctor. Doesn't really do anything.
Definition Tasks.h:302
int step()
Function to step the Event. This will be called every step, but only call execute when triggered.
Definition Tasks.cpp:169
Event(Executive &executive, int schedule_slot=0, const std::string &m_name="Unnamed")
Executive-based constructor for the task.
Definition Tasks.h:298
Central control mechanism to run simulations and software.
Definition Executive.h:43
Base class for object organization.
Definition GraphTreeObject.h:87
Base class implementation of the monitor.
Definition Tasks.h:212
virtual ~Monitor()
Desrtuctor. Doesn't really do anything.
Definition Tasks.h:236
DataIO< bool > latch
Our latch flag – If true, the monitor will continue to return triggered even after conditions change.
Definition Tasks.h:251
void reset()
Function to reset the monitor's trigger to false.
Definition Tasks.h:243
Monitor(Executive &executive, int schedule_slot=0, const std::string &m_name="Unnamed")
Executive-based constructor for the task.
Definition Tasks.h:232
Monitor(Task &pnt, int schedule_slot=0, const std::string &m_name="Unnamed")
Task-based constructor for the task. Auto-assigns executive.
Definition Tasks.h:224
int step()
Function to step the monitor. This will be called every step.
Definition Tasks.cpp:139
DataIO< bool > trigger
Our trigger – this is the flag set and unset by the monitor as its ultimate output,...
Definition Tasks.h:247
Monitor()
Default constructor for the task object for simplicity. Note: Masks some functionality and should not...
Definition Tasks.h:217
This is the base implementation of the task class.
Definition Tasks.h:68
Task(Executive &executive, const std::string &m_name="Unnamed")
Executive-based constructor for the task.
Definition Tasks.cpp:35
int rangeCheck(double min, double max, DataIO< double > signal)
Overloaded function to check range on a parameter.
Definition Tasks.cpp:113
int startup()
Function to perform startup activities (step once at start after creation). Should not be modified in...
Definition Tasks.cpp:77
Task()
Default constructor for the task object for simplicity. Note: Masks some functionality and should not...
Definition Tasks.cpp:21
log_level_e _local_log_level
Our local log level – allows a higher log level locally than the overall system.
Definition Tasks.h:175
Task(Task &pnt, const std::string &m_name="Unnamed")
Task-based constructor for the task. Auto-assigns executive.
Definition Tasks.cpp:23
Task(Task &pnt, int slot, const std::string &m_name="Unnamed")
Task-based constructor for the task. Auto-assigns executive.
Definition Tasks.cpp:47
Executive * exc
Pointer to the executive object.
Definition Tasks.h:184
DataIO< Time > entry_time
Time of entry (per wallClockTimer) of the last step of this task.
Definition Tasks.h:143
void recordTiming()
Function to command this task to record timing information.
Definition Tasks.h:130
DataIO< int > schedule_slot
The schedule slot this task will step in – set to 0 by default.
Definition Tasks.h:140
Task(Executive &executive, int slot, const std::string &m_name="Unnamed")
Executive-based constructor for the task.
Definition Tasks.cpp:62
bool _record_timing
Variable to enable or disable timing.
Definition Tasks.h:181
int _error
Simple variable to track error in task.
Definition Tasks.h:178
DataIO< bool > active
The active flag for the task – set to true by default.
Definition Tasks.h:137
virtual int start()
Function to perform task startup activities (step once after creation)
Definition Tasks.h:153
virtual ~Task()
Desrtuctor. Doesn't really do anything.
Definition Tasks.h:100
virtual int deactivate()
Function to deactivate the task.
Definition Tasks.h:127
virtual int step()
Function to step the task. This will be called every step.
Definition Tasks.cpp:89
DataIO< Time > exit_time
Time of exit (per wallClockTimer) of the last step of this task.
Definition Tasks.h:146
virtual int execute()
Function to execute the task. All math and calculations should be here.
Definition Tasks.h:160
virtual int activate()
Function to activate the task.
Definition Tasks.h:120
void logLevel(log_level_e new_level)
Function to set the local model log level.
Definition Tasks.h:134
Wrapper to manage and convert time as timespce.
Definition Time.h:45
Time()
Default, copy constructors and default destructor.
Definition Time.h:48
#define NO_ERROR
Definition clockwerkerrors.h:31