Module Definition File

The module function is defined in the SomeModule.c file. This page outlines key expected behaviors.

SelfInit Method

A C code does not have constructors. Thus, the Basilisk C module must define a self initialization function to ensure the output messages are setup to write to themselves. This is shown in the sample code below.

/*!
    This method initializes the output messages for this module.
 @return void
 @param configData The configuration data associated with this module
 @param moduleID The module identifier
 */
void SelfInit_someModule(someModuleConfig *configData, int64_t moduleID)
{
    SomeMsg_C_init(&configData->someOutMsg);
}

Warning

The SelfInit function should only do the above steps. Don’t try to set default module variables here as the configData structure is zero’d in Swig when this structure copy is created in Python. Thus, for C modules all default config structure variables are zero!

Reset Method

The Reset_....() method should be used to

  • restore module variables if needed. For example, the integral feedback gain variable might be reset to 0.

  • perform one-time message reads such as reading in the reaction wheel or spacecraft configuration message etc. Whenever Reset() is called the module should read in these messages again to use the latest values.

  • check that required input messages are connected. If a required input message is not connected when Reset() is called, then log a BSK error message.

The following sample code assumes that the class variable value should be re-set to 0 on Reset(), and that someInMsg is a required input message:L

/*! This method performs a complete reset of the module.  Local module variables that retain
 time varying states between function calls are reset to their default values.
 @return void
 @param configData The configuration data associated with the module
 @param callTime [ns] time the method is called
 @param moduleID The module identifier
*/
void Reset_someModule(someModuleConfig *configData, uint64_t callTime, int64_t moduleID)
{
    configData->value = 0.0;

    if (!SomeMsg_C_isLinked(&configData->someInMsg) {
        char info[MAX_LOGGING_LENGTH];
        sprintf(info, "SomeModule does not have someInMsg connected!);
        _bskLog(configData->bskLogger, BSK_ERROR, info);
    }
}

Note that doing a Basilisk log in a C module is different and than within a C++ module.

Update Method

The Update_....() function is called each time the Basilisk simulation runs the C module. This method needs to perform all the required BSK module function, including reading in input messages and writing to output messages. In the sample code below the message reading and writing, as well as the module function is done directly within this function. Some modules also create additional functions to separate out the various functions. This is left up to the module developer as a code design choice.

/*! Add a description of what this main Update() routine does for this module
 @return void
 @param configData The configuration data associated with the module
 @param callTime The clock time at which the function was called (nanoseconds)
 @param moduleID The module identifier
*/
void Update_someModule(someModuleConfig *configData, uint64_t callTime, int64_t moduleID)
{
    SomeMsgPayload outMsgBuffer;       /*!< local output message copy */
    SomeMsgPayload inMsgBuffer;        /*!< local copy of input message */

    // always zero the output buffer first
    outMsgBuffer = SomeMsg_C_zeroMsgPayload();

    /*! - Read the input messages */
    inMsgBuffer = SomeMsg_C_read(&configData->someInMsg);

    /* As an example of a module function, here we simply copy input message content to output message. */
    v3Copy(inMsgBuffer.dataVector, outMsgBuffer.dataVector);

    /*! - write the module output message */
    SomeMsg_C_write(&outMsgBuffer, &configData->someOutMsg, moduleID, callTime);
}

Warning

It is critical that each module zeros the content of the output messages on each update cycle. This way we are not writing stale or uninitialized data to a message. When reading a message BSK assumes that each message content has been either zero’d or written to.

Array of Messages

Assume the module has an array called moreInMsgs which contain input message objects of type SomeMsg_C. Interfacing with these messages is done in a standard C manner with how elements of an array are retrieved. For example, to read the 3-slot of the input array the code could read as

inMsgBuffer = SomeMsg_C_read(&configData->moreInMsgs[3]);