Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 63 additions & 6 deletions include/trick/DataRecordGroup.hh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ PROGRAMMERS:

namespace Trick {

class DataRecordGroup;

/**
* The DR_Freq enumeration represents the possible Trick data recording frequency.
*/
Expand Down Expand Up @@ -70,12 +72,27 @@ namespace Trick {
LoggingCycle(double rate_in);
LoggingCycle() = default;
void set_rate(double rate_in);
static long long calc_next_tics_on_or_after_input_tic(long long input_tic, long long cycle_tic);
double rate_in_seconds{}; /* (s) Logging rate in seconds */
long long rate_in_tics{}; /* (--) Logging rate in sim tics */
long long next_cycle_in_tics{}; /* (--) Next cycle in tics for logging */
};

class DataRecordGroup : public Trick::SimObject {
class DataRecordGroupJobData : public JobData
{
public:
DataRecordGroupJobData(DataRecordGroup & owner_in);
DataRecordGroupJobData(DataRecordGroup & owner_in, int in_thread, int in_id, std::string in_job_class_name , void* in_sup_class_data,
double in_cycle, std::string in_name, std::string in_tag = "", int in_phase = 60000 ,
double in_start = 0.0 , double in_stop = 1.0e37);

int set_cycle(double rate) override;
void enable() override;

DataRecordGroup & owner;
};

class DataRecordGroup : public SimObject {

public:

Expand All @@ -100,9 +117,6 @@ namespace Trick {
/** Start time for data recording.\n */
double start; /**< trick_io(*io) trick_units(s) */

/** Cycle time for data recording.\n */
double cycle; /**< trick_io(*io) trick_units(s) */

/* Fake attributes to use for data recording.\n */
ATTRIBUTES time_value_attr; /**< trick_io(**) */

Expand Down Expand Up @@ -192,6 +206,18 @@ namespace Trick {
*/
int set_job_class(std::string in_class) ;

/**
* Get the total number of rates for this DataRecordGroup instance
* @return total number of rates
*/
size_t get_num_rates();

/**
* Get the logging rate according to rate index
* @return cycle in seconds or -1.0 if error
*/
double get_rate(const size_t rateIdx = 0);

/**
@brief @userdesc Command to set the rate at which the group's data is recorded (default is 0.1).
@par Python Usage:
Expand All @@ -206,10 +232,19 @@ namespace Trick {
@par Python Usage:
@code <dr_group>.add_cycle(<in_cycle>) @endcode
@param in_cycle - the recording rate in seconds
@return always 0
@return vector index of the added rate
*/
int add_cycle(double in_cycle) ;

/**
* Updates a logging rate by index and cycle. Calling with 0
* index is equivalent to set_cycle
* @param rate_idx index of the added rate
* @param rate_in New integration rate in seconds
* @return Zero = success, non-zero = failure (rateIdx is invalid).
*/
int set_rate(const size_t rate_idx, const double rate_in);

/**
@brief @userdesc Command to set the phase where the group's data is record (default is 60000).
@par Python Usage:
Expand Down Expand Up @@ -450,26 +485,48 @@ namespace Trick {
/** Data thread condition mutex. */
pthread_mutex_t buffer_mutex; /**< trick_io(**) */

/** Current time saved in Trick::DataRecordGroup::data_record.\n */
/** Current time saved in Trick::DataRecordGroup::data_record when a buffer is written \n */
double curr_time ; /**< trick_io(*i) trick_units(--) */

/** Current time saved in Trick::DataRecordGroup::data_record the job was recorded. \n */
double curr_time_dr_job ; /**< trick_io(*i) trick_units(--) */

/**
* Vector of logging rate objects.
*/
std::vector<LoggingCycle> logging_rates;

/**
* Loop through the required logging rates and check if the rates are valid for the time tic value
* @return true if valid, false if an error is detected
*/
bool check_if_rates_are_valid();

/**
* Check if a rate is valid for logging. An invalid rate is detected by
* - being smaller than the time tic value (or 0)
* - not being a whole number when converted to tics *
* @param test_rate Test rate in seconds
* @return 0 if valid, 1 if too small, 2 if it cannot be exactly scheduled
*/
int check_if_rate_is_valid(double test_rate);

/**
* Loop through the required logging rates and calculate the
* next logging time in tics.
* @return Next logging time in tics,
*/
long long calculate_next_logging_tic(long long min_tic);

void emit_rate_error(int rate_err_code, size_t log_idx, double err_rate);

/**
* Loop through the required logging rates and advance the next cycle tics of matching rates
* @param curr_tic_in - time in tics to match and advance the next cycle tic
*/
void advance_log_tics_given_curr_tic(long long curr_tic_in);

static const double default_cyle;
} ;

} ;
Expand Down
4 changes: 2 additions & 2 deletions include/trick/JobData.hh
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,12 @@ namespace Trick {
/**
* Enable the job.
*/
void enable() ;
virtual void enable() ;

/**
* Disable the job.
*/
void disable() ;
virtual void disable() ;

/**
* Sets the job is handled flag
Expand Down
6 changes: 3 additions & 3 deletions include/trick/MultiDtIntegLoopScheduler.hh
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ public:

/**
* Updates an integration rate by index and cycle. Calling with 0
* index is equivalent to set_integ_cycle
* @param rateIdx New integration rate in seconds
* @param integRateIn index of the added rate
* index is equivalent to set_integ_cycle *
* @param rateIdx index of the added rate
* @param integRateIn New integration rate in seconds
* @return Zero = success, non-zero = failure (rateIdx is invalid).
*/
virtual int set_integ_rate(const size_t rateIdx, const double integRateIn);
Expand Down
10 changes: 8 additions & 2 deletions test/SIM_checkpoint_data_recording/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,18 @@ RUN started with different logging setup
Checkpoint loaded at t=5
Expected: logging with multiple rates to start from t=7.01+ with no offset

RUN_test10
Configured the increment job to execute at 0.1
A runtime invalid set_cycle of 0 is attempted and a set_cycle of 1/128 which the time_tic_value cannot support are both rejected and logging happens as if neither commands are attempted
Checkpoint dumped with at t=7.01 with multiple loggings rates and multiple calls to set the cycle of both rates throughout the RUN
RUN started with different logging setup
Checkpoint loaded at t=5
Expected: the varying logging rates specified in add_reads to be processed starting from t=7.01+ with no offset.

RUN_test11 and RUN_test11_redirect
RUN_test11 runs with data recording and drops a checkpoint at 5.5 seconds
RUN_test11_redirect loads the checkpoint from RUN_test11 at time = 0.0 and redirects the output to its own directory
Expected: ref_log_foo and log_foo in RUN_test11 should match, showing that the checkpoint did not overwrite previous data;
ref_log_foo and log_foo in RUN_test11_redirect should match, showing that the checkpoint redirected output to the new dir.



Overall: expectation is that what loads in from the checkpoint should take precedence and overwrite the file of the same name - expect for RUN_test11*.
48 changes: 48 additions & 0 deletions test/SIM_checkpoint_data_recording/RUN_test10/dump.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import trick
from trick.unit_test import *

# This was just here for convenience to dump the checkpoints.

def main():
exec(open("Modified_data/foo2.dr").read())

dr_group = drg[DR_GROUP_ID]

dr_group.set_cycle(0.1)
dr_group.add_cycle(100.0)

trick.checkpoint(7.01)

trick.exec_set_job_cycle("testSimObject.my_foo.increment", 0, 0.1)

ss_end = 1800.0
cs_end = 3600.0
cs_logging_break = 2879.66
second_cycle_update = ((cs_end-1.1)+(ss_end+2.4))/2
ph_logging_break = 1796.6
stop_time = cs_end+2.6+10.0

print("time 0, cycle = 0.1")
print(f'time {2.4}, cycle = {ph_logging_break}')
print(f'time {ss_end-1.1}, cycle = {0.1}')
print(f'time {ss_end+2.4}, cycle = {cs_logging_break}')
print(f'time {second_cycle_update}, 2nd cycle = {cs_logging_break/4}')
print(f'time {cs_end-1.1}, cycle = {0.1}')
print(f'time {stop_time-6.9}, disable job')
print(f'time {stop_time-4.5}, enable job')
print(f'stop = {stop_time}')

trick.add_read(2.4,f'trick.exec_set_job_cycle("trick_data_record_group_{dr_group.get_group_name()}.data_record", 1, {ph_logging_break})')
trick.add_read(ss_end-1.1,f'trick.get_data_record_group("{dr_group.get_group_name()}").set_cycle(0.1)')
trick.add_read(ss_end+2.4,f'trick.get_data_record_group("{dr_group.get_group_name()}").set_cycle({cs_logging_break})')
trick.add_read(second_cycle_update,f'trick.get_data_record_group("{dr_group.get_group_name()}").set_rate(1, {cs_logging_break/4})')
trick.add_read(cs_end-1.1,f'trick.get_data_record_group("{dr_group.get_group_name()}").set_cycle(0.1)')
trick.add_read(1.0, f'trick.get_data_record_group("{dr_group.get_group_name()}").set_cycle(0.0)')
trick.add_read(2.0, f'trick.get_data_record_group("{dr_group.get_group_name()}").set_rate(1, {1/128})')
trick.add_read(2.0, f'trick.get_data_record_group("{dr_group.get_group_name()}").set_rate(1, {1/128})')
trick.add_read(stop_time-6.9, f'trick.exec_set_job_onoff("trick_data_record_group_{dr_group.get_group_name()}.data_record", 1, 0)')
trick.add_read(stop_time-4.5, f'trick.exec_set_job_onoff("trick_data_record_group_{dr_group.get_group_name()}.data_record", 1, 1)')
trick.stop(stop_time)

if __name__ == "__main__":
main()
Loading
Loading