diff --git a/.github/scripts/run_long_fuzzers.sh b/.github/scripts/run_long_fuzzers.sh index 83a2e06e3..30ecb073e 100755 --- a/.github/scripts/run_long_fuzzers.sh +++ b/.github/scripts/run_long_fuzzers.sh @@ -68,8 +68,14 @@ while IFS= read -r fuzz_bin; do if [[ -n "$FUZZ_DURATION" ]]; then cmd+=("--fuzz_for=${FUZZ_DURATION}") fi + env_vars=() if [[ -n "$CORPUS_DIR" ]]; then - cmd+=("--corpus_database=${CORPUS_DIR}") + fuzz_corpus_dir="${CORPUS_DIR}/${fuzz_name}" + mkdir -p "$fuzz_corpus_dir" + env_vars+=( + "FUZZTEST_TESTSUITE_OUT_DIR=${fuzz_corpus_dir}" + "FUZZTEST_TESTSUITE_IN_DIR=${fuzz_corpus_dir}" + ) fi - "${cmd[@]}" | tee "$LOG_DIR/${fuzz_name}.log" + env "${env_vars[@]}" "${cmd[@]}" 2>&1 | tee "$LOG_DIR/${fuzz_name}.log" || true done <<< "$FUZZ_BINS" diff --git a/.github/workflows/nightly-long-tests.yml b/.github/workflows/nightly-long-tests.yml index fbc2da0fa..29362e4e9 100644 --- a/.github/workflows/nightly-long-tests.yml +++ b/.github/workflows/nightly-long-tests.yml @@ -2,8 +2,12 @@ name: Nightly Long Tests on: schedule: - - cron: "0 0 * * *" + - cron: '0 7 * * *' # midnight MDT (07:00 UTC) workflow_dispatch: + inputs: + fuzz_duration: + description: 'Duration per fuzz target (e.g. 120s, 10m)' + default: '600s' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -27,11 +31,11 @@ jobs: packages: write actions: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Restore fuzz corpus cache id: fuzz-corpus-cache - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 with: path: .fuzztest_corpus key: fuzz-corpus-${{ runner.os }}-${{ github.run_id }} @@ -126,13 +130,42 @@ jobs: ASAN_OPTIONS: detect_leaks=1:strict_string_checks=1:check_initialization_order=1 UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1:suppressions=/dev/null run: | + FUZZ_DURATION="${{ inputs.fuzz_duration || '600s' }}" "${GITHUB_WORKSPACE}/.github/scripts/run_long_fuzzers.sh" "$(pwd)" "${GITHUB_WORKSPACE}/fuzz-logs" \ - --fuzz-for 600s \ + --fuzz-for "$FUZZ_DURATION" \ --corpus "${XMERA_FUZZTEST_CORPUS_DIR}" + - name: Generate fuzz report summary + if: ${{ always() }} + run: | + { + echo "## Nightly Fuzz Report — $(date -u +%Y-%m-%d)" + echo "" + echo "| Target | Corpus Files | Status |" + echo "|--------|-------------|--------|" + + for log in fuzz-logs/*.log; do + [[ -f "$log" ]] || continue + name="$(basename "$log" .log)" + + corpus_count=0 + if [[ -d ".fuzztest_corpus" ]]; then + corpus_count=$(find ".fuzztest_corpus" -type f -path "*${name}*" 2>/dev/null | wc -l || echo 0) + fi + + if grep -qiE '(SUMMARY:.*Sanitizer|crash-|==ERROR)' "$log" 2>/dev/null; then + status="CRASH" + else + status="OK" + fi + + echo "| ${name} | ${corpus_count} | ${status} |" + done + } >> "$GITHUB_STEP_SUMMARY" + - name: Archive fuzz logs if: ${{ always() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: fuzz-logs path: fuzz-logs @@ -140,15 +173,16 @@ jobs: - name: Upload fuzz corpus artifact if: ${{ always() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: fuzz-corpus-${{ github.run_id }} - path: .fuzztest_corpus + path: ${{ github.workspace }}/.fuzztest_corpus/ + include-hidden-files: true retention-days: 7 - name: Save fuzz corpus cache if: ${{ always() }} - uses: actions/cache/save@v4 + uses: actions/cache/save@v5 with: path: .fuzztest_corpus key: fuzz-corpus-${{ runner.os }}-${{ github.run_id }} diff --git a/docs/source/developer/fuzz-testing.rst b/docs/source/developer/fuzz-testing.rst new file mode 100644 index 000000000..208b95fdb --- /dev/null +++ b/docs/source/developer/fuzz-testing.rst @@ -0,0 +1,297 @@ + +.. _fuzz-testing: + +Fuzz Testing +============ + +Fuzz testing automatically generates randomized inputs to find crashes, assertion +violations, and other bugs that hand-written test cases miss. Xmera uses +`Google FuzzTest `__ to write fuzz tests +alongside regular GTest unit tests. + +Goals +----- + +Fuzz testing in Xmera serves three purposes: + +1. **Find crashes and undefined behavior** -- the fuzzer explores input + combinations that humans rarely think to try (overflows, empty arrays, + extreme values). + +2. **Verify algorithmic invariants** -- rather than checking a single expected + output, fuzz tests assert properties that must hold for *all* valid inputs + (e.g., "pixel count is non-negative", "merged region does not exceed sum of + inputs"). + +3. **Continuous regression coverage** -- a nightly CI job runs each fuzz target + for an extended duration and persists a corpus of interesting inputs. Over + time the corpus grows, giving each subsequent run a head start. + + +Property-Based Tests (Fuzz Tests) +--------------------------------- + +Traditional unit tests verify specific input/output pairs: + +.. code-block:: cpp + + // Unit test: one specific scenario + EXPECT_EQ(algorithm.update(knownInput), expectedOutput); + +Property-based fuzz tests instead assert *invariants* that hold across the +entire input domain: + +.. code-block:: cpp + + // Fuzz test: any valid input must satisfy these properties + void fuzzAlgorithm(int32_t x, int32_t y) { + auto result = algorithm.update(x, y); + EXPECT_GE(result.count, 0); // never negative + EXPECT_LE(result.count, x + y); // bounded by inputs + } + FUZZ_TEST(MySuite, fuzzAlgorithm) + .WithDomains(fuzztest::InRange(0, 1000), + fuzztest::InRange(0, 1000)); + +When built without fuzzing instrumentation (the default), each ``FUZZ_TEST`` +runs as a normal parameterized GTest with a fixed set of seed inputs -- so it +participates in regular CI without any special build flags. When built with +``FUZZTEST_FUZZING_MODE=ON``, the same test becomes a coverage-guided fuzzer +that mutates inputs to maximize code coverage. + + +Creating a Fuzz Test +-------------------- + +File layout +~~~~~~~~~~~ + +Place fuzz tests next to the existing unit tests for a module. The naming +convention is ``test__fuzz.cpp``: + +.. code-block:: none + + src/fswAlgorithms/// + tests/ + CMakeLists.txt + test_.cpp # regular GTest + test__fuzz.cpp # fuzz tests + +Writing the test file +~~~~~~~~~~~~~~~~~~~~~ + +A fuzz test file has three parts: + +1. **Includes** -- the algorithm header, GTest, and FuzzTest: + + .. code-block:: cpp + + #include "../myAlgorithm.h" + #include "gtest/gtest.h" + #include + +2. **Test functions** -- each function takes fuzzed parameters and asserts + invariants. The function must not return a value; use ``EXPECT_*`` / + ``ASSERT_*`` macros to check properties: + + .. code-block:: cpp + + void fuzzMyAlgorithm(int32_t inputA, double inputB) { + MyAlgorithm algo; + auto result = algo.compute(inputA, inputB); + + // Assert invariants -- properties that must hold for ALL inputs + EXPECT_GE(result.value, 0); + EXPECT_NO_THROW(algo.reset()); + } + +3. **Registration** -- the ``FUZZ_TEST`` macro registers the function and + specifies input domains: + + .. code-block:: cpp + + FUZZ_TEST(MyAlgorithmFuzz, fuzzMyAlgorithm) + .WithDomains(fuzztest::InRange(0, 1000), // inputA + fuzztest::InRange(-1.0, 1.0)); // inputB + + Common domain combinators: + + - ``fuzztest::InRange(lo, hi)`` -- uniformly sample an integer or float range + - ``fuzztest::OneOf(domain1, domain2, ...)`` -- pick from several sub-domains + - ``fuzztest::Arbitrary()`` -- any value of type ``T`` + - ``fuzztest::VectorOf(domain).WithMaxSize(n)`` -- variable-length containers + + See the `FuzzTest domain reference `__ + for the full list. + +CMake integration +~~~~~~~~~~~~~~~~~ + +In the module's ``tests/CMakeLists.txt``, add a conditional fuzz target: + +.. code-block:: cmake + + if(XMERA_ENABLE_FUZZTESTS) + fuzztest_setup_fuzzing_flags() + + add_executable(test_myModule_fuzz + ../myAlgorithm.cpp + test_myModule_fuzz.cpp + ) + + target_link_libraries(test_myModule_fuzz PRIVATE + Eigen3::Eigen + fuzztest::fuzztest + fuzztest::fuzztest_gtest_main + ) + + gtest_discover_tests(test_myModule_fuzz + PROPERTIES + LABELS "fuzz\;fuzz-smoke" + ) + endif() + +Key points: + +- Guard everything with ``if(XMERA_ENABLE_FUZZTESTS)`` so the default build is + unaffected. +- Call ``fuzztest_setup_fuzzing_flags()`` before ``add_executable`` to configure + the necessary compiler instrumentation. +- Link against ``fuzztest::fuzztest`` and ``fuzztest::fuzztest_gtest_main`` + (not ``GTest::gtest_main``). +- Apply both the ``fuzz`` and ``fuzz-smoke`` CTest labels so the target is + picked up by both smoke and long-running fuzz workflows. + +Writing good invariants +~~~~~~~~~~~~~~~~~~~~~~~ + +The hardest part of fuzz testing is choosing what to assert. Some strategies: + +- **No crash** -- the simplest invariant. If the function segfaults or throws an + unhandled exception on *any* input, that is a bug. +- **Output bounds** -- result values stay within a known range + (``EXPECT_GE(result, 0)``). +- **Conservation** -- output does not exceed a known function of the inputs + (e.g., merged pixel count <= sum of input pixel counts). +- **Idempotence** -- calling the function twice with the same input gives the + same result. +- **Round-trip** -- encode then decode returns the original value. +- **Reference oracle** -- compare a fast implementation against a known-correct + slow implementation. + + +Running Fuzz Tests +------------------ + +There are three ways to run fuzz tests, depending on what you need. + +As regular unit tests (smoke test) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Configure with the ``fuzz-smoke-test`` preset and run via CTest. Each +``FUZZ_TEST`` executes a small fixed set of seed inputs as a normal GTest -- +no coverage-guided fuzzing, just a quick sanity check: + +.. code-block:: bash + + cd src + cmake --preset fuzz-smoke-test + cmake --build ../build --parallel + cd ../build && ctest -C Release -L fuzz-smoke + +This is what PR CI runs. It finishes in seconds. + +As a coverage-guided fuzzer (local) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Configure with the ``fuzz-test`` preset (enables ``FUZZTEST_FUZZING_MODE``), +then run a specific binary with ``--fuzz_for``: + +.. code-block:: bash + + cd src + cmake --preset fuzz-test + cmake --build ../build --parallel + ./build/path/to/test_myModule_fuzz --fuzz_for=120s + +The fuzzer will mutate inputs for the specified duration, printing new coverage +discoveries to the terminal. If it finds a crash, it prints the reproducer +input and exits with a non-zero status. + +To run all fuzz targets for a fixed duration, use the helper script: + +.. code-block:: bash + + .github/scripts/run_long_fuzzers.sh ./build ./fuzz-logs --fuzz-for 120s + +With a persistent corpus +~~~~~~~~~~~~~~~~~~~~~~~~~ + +A *corpus* is a set of inputs that the fuzzer has previously found interesting +(i.e., they exercise distinct code paths). Persisting the corpus between runs +lets the fuzzer pick up where it left off instead of starting from scratch. + +To save and reuse a corpus, set the ``FUZZTEST_TESTSUITE_OUT_DIR`` and +``FUZZTEST_TESTSUITE_IN_DIR`` environment variables: + +.. code-block:: bash + + # First run -- seed the corpus + mkdir -p /tmp/fuzz-corpus + FUZZTEST_TESTSUITE_OUT_DIR=/tmp/fuzz-corpus \ + FUZZTEST_TESTSUITE_IN_DIR=/tmp/fuzz-corpus \ + ./build/path/to/test_myModule_fuzz --fuzz_for=60s + + # Subsequent runs -- the fuzzer loads previous findings and continues + FUZZTEST_TESTSUITE_OUT_DIR=/tmp/fuzz-corpus \ + FUZZTEST_TESTSUITE_IN_DIR=/tmp/fuzz-corpus \ + ./build/path/to/test_myModule_fuzz --fuzz_for=60s + +Corpus files are written **incrementally during fuzzing** -- they survive +crashes and early termination. This is in contrast to ``--corpus_database``, +which only writes the corpus after a clean exit. + +The ``run_long_fuzzers.sh`` script handles corpus management automatically when +given the ``--corpus`` flag: + +.. code-block:: bash + + .github/scripts/run_long_fuzzers.sh ./build ./fuzz-logs \ + --fuzz-for 120s --corpus .fuzztest_corpus + +This creates per-binary subdirectories under ``.fuzztest_corpus/`` (e.g., +``.fuzztest_corpus/test_regionsOfInterest_fuzz/``) and sets the environment +variables for each binary. + + +Nightly CI Fuzzing +------------------ + +The ``nightly-long-tests.yml`` workflow runs every night and: + +1. Restores the corpus cache from prior runs. +2. Configures and builds with the ``fuzz-test`` preset. +3. Runs ``run_long_fuzzers.sh`` with a 120-second (or configurable) duration + per target. +4. Saves the updated corpus back to the GitHub Actions cache. +5. Uploads logs and the corpus as workflow artifacts. + +The corpus accumulates over time. Each nightly run starts from the previous +night's corpus, so coverage improves monotonically. + +To trigger a manual nightly run with a custom duration, use the workflow +dispatch from the Actions tab and set the ``fuzz_duration`` input (e.g., +``10m``). + +Reproducing a Failure +--------------------- + +When the fuzzer finds a crash, it prints the failing input to the console. To +reproduce it: + +1. Copy the ``FUZZ_TEST_*`` reproducer line from the log. +2. Set the ``FUZZ_TEST_MINIMIZER_INPUT`` environment variable as shown in the + log and re-run the binary. The fuzzer will minimize the input to the + smallest case that still triggers the failure. +3. Add the minimal reproducing input as a regular GTest case so the fix is + permanently covered by CI. diff --git a/docs/source/developer/index.rst b/docs/source/developer/index.rst index 16b6cd1e6..50ff38d26 100644 --- a/docs/source/developer/index.rst +++ b/docs/source/developer/index.rst @@ -10,10 +10,9 @@ The following support files help with writing Xmera modules. code-guidelines debugging + fuzz-testing deprecating-code making-new-module add-sphinx-docs module-checklist understanding-xmera - migrating-module-to-bsk2 - migrating-to-python3 diff --git a/docs/source/developer/making-new-module.rst b/docs/source/developer/making-new-module.rst index 8b44d0542..c75073fbd 100644 --- a/docs/source/developer/making-new-module.rst +++ b/docs/source/developer/making-new-module.rst @@ -47,7 +47,7 @@ Linear Algebra and Kinematics Support If your module includes vector or tensor math: -- Refer to the :ref:`codingGuidelines` for naming conventions related to matrix representations. +- Refer to the :ref:`code-guidelines` for naming conventions related to matrix representations. - For C++ modules, Xmera supports the `Eigen library `_. Keep in mind that Eigen's ``.toRotationMatrix()`` method returns the direction cosine matrix (DCM) :math:`[NB]`, not :math:`[BN]`. Xmera's Eigen MRP implementation follows this same convention. diff --git a/docs/source/developer/migrating-module-to-bsk2.rst b/docs/source/developer/migrating-module-to-bsk2.rst deleted file mode 100644 index 68abd4e2d..000000000 --- a/docs/source/developer/migrating-module-to-bsk2.rst +++ /dev/null @@ -1,466 +0,0 @@ - -.. _migrating-module-to-bsk2: - -Migrating Xmera Modules from Version 1.X to 2.X -================================================== - -Motivation ----------- -This document discusses what coding related changes occurred with the new messaging -system in Xmera version 2.0 -and higher. However, nothing is for free. Making these changes was not possible without breaking existing code. -This migration -help page outlines all the Xmera coding related changes that have occurred. -This facilities the process of upgrading legacy -Xmera C and C++ code to function with the new message system, etc. - -For changes related to updating Xmera python scripts, see :ref:`migrating-module-to-bsk2`. - - -Message Names -------------- -See :ref:`migrating-module-to-bsk2` for the discussion on how module input and output messages no longer -have name and ID variables. - -Creating New Message Definitions --------------------------------- -See :ref:`bsk2MessageDefinition` for how new message C structures can be created and added to the -Xmera project. - -Step-By-Step Guide to Upgrade a Xmera Modules ------------------------------------------------- -All the existing BSK 1.x messaging functionality exists with the new BSK 2.0 messaging system. -This facilitates the migration to 2.0 as it requires some commands to be changed, but -none of the code logic should have to change. As before, the message interfaces vary between -C and C++ modules. - -Changed Importing of Some Files -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If your module uses:: - - #include "simulation/simFswInterfaceMessages/macroDefinitions.h" - -this file has now moved to:: - - #include "architecture/utilities/macroDefinitions.h" - -Further, all includes should be done relative to the ``Xmera/src`` directory. This means:: - - #include "sensors/magnetometer/magnetometer.h" - -should be changed to:: - - #include "simulation/sensors/magnetometer/magnetometer.h" - - -Updating a C Module -^^^^^^^^^^^^^^^^^^^ - -#. Updating the ``module.h`` file: - - - Remove the import of the C interface to the old messaging system, delete this line - - .. code:: cpp - - #include "messaging/static_messaging.h" - - The message wrappers being included below replace this step. - - - Update the ``#include`` statement to read in the message definition through - - .. code:: cpp - - #include "cMsgCInterface/ModuleMsg_C.h" - - This import provides access to the message object as well as the C message structure definition. - - - Replace the ``char`` message name variable ``moduleOutMsgName`` and associated - ``int_32t`` message ID variable ``moduleOutMsgId`` with - - .. code:: cpp - - ModuleMsg_C moduleOutMsg; // sensor output message - ModuleMsg_C moduleInMsg; // sensor input message - - Note that the ``Fsw``, ``Int`` and ``Sim`` message distinctions are now dropped in the new - messaging system. This step is the same regardless if this message connects to/from a C or - C++ Xmera module. - - - If you want to create an array of output messages, this can be done with - - .. code:: cpp - - SomeMsg_C descriptionOutMsgs[10]; - - - Remove the ``CrossInit_xxxx()`` method, it is no longer used. If you initialized any code in this function, move that code to the module ``Reset_xxxx()`` function. - - - Clean up the ``SelfInit_xxxx()`` method to only initialize the output messages. All other code and setup should be moved to the ``Reset_xxxx()`` function. - - -#. Updating the ``module.c`` file: - - - To initialize the module output message in ``SelfInit_xxxx()``, replace - - .. code:: cpp - - configData->moduleOutMsgId = CreateNewMessage(configData->moduleOutMsgName, - sizeof(ModuleFswOutMsg), "ModuleFswOutMsg", moduleID); - - with - - .. code:: cpp - - ModuleMsg_C_init(&configData->moduleOutMsg); - - - To check if an output message has been linked to other input message, use - - .. code:: cpp - - ModuleMsg_C_isLinked(&configData->moduleOutMsg); - - - To connect to an input message, delete - - .. code:: cpp - - configData->moduleInMsgId = subscribeToMessage(configData->moduleInMsgName, - sizeof(ModuleFswMsg), moduleID); - - The input messages are connected when then Xmera simulation is scripted in python. No - additional code is required in your C code. Remove the ``CrossInit_xxxx()`` method, - it is no longer used. If you initialized any code in this function, move that code - to the module ``Reset_xxxx()`` function. - - - - To create a local variable of the message content structure (payload) itself, use - - .. code:: cpp - - ModuleMsgPayload msgBuffer; - - - To read in a message, replace - - .. code:: cpp - - ModuleFswMsg msgBuffer; - memset(&msgBuffer, 0x0, sizeof(ModuleFswMsg)); - ReadMessage(configData->moduleInMsgId, &timeOfMsgWritten, &sizeOfMsgWritten, - sizeof(ModuleFswMsg), (void*) &(sc), msgBuffer); - - with - - .. code:: cpp - - ModuleMsgPayload msgBuffer; - msgBuffer = ModuleMsg_C_read(&configData->moduleInMsg); - - - To check is a message has been connected to, check the value of ``ModuleMsg_C_isLinked()`` - - To check if a message has ever been written to, check the value of ``ModuleMsg_C_isWritten()`` - - To get the time when a message was written, use ``ModuleMsg_C_timeWritten()`` - - To get the ID of the module who wrote the message, use ``ModuleMsg_C_moduleID()`` - - - To zero a message payload variable ``someMsgBuffer`` of type ``SomeMsgPayload``, - remove the use of ``memset()`` and use the C++ default initializer instead: - - .. code:: cpp - - SomeMsgPayload someMsgBuffer{}; - - - To write to an output message, assuming ``outputMsgBuffer`` is a local variable holding - the message content (payload), replace - - .. code:: cpp - - memset(&outputMsgBuffer, 0x0, sizeof(ModuleFswMsg)); - outputMsgBuffer.variable = 42; // specify output msg values - WriteMessage(configData->moduleOutMsgId, callTime, sizeof(ModuleIntMsg), - (void*) &(outputMsgBuffer), moduleID); - - with - - .. code:: cpp - - ModuleMsgPayload outputMsgBuffer{}; - outputMsgBuffer.variable = 42; // specify output msg values - ModuleMsg_C_write(&outputMsgBuffer, &configData->moduleOutMsg, moduleID, callTime); - - Note that you should still zero-initialize the local ``outputMsgBuffer`` structure with ``{}`` so that the - message has zero default values if some fields are not set. - -#. Updating the ``module.i`` file: - - - In the ``GEN_SIZEOF()`` commands used to be used to get the size of a message in Python. This is no longer - required with the new message system. Thus, these ``GEN_SIZEOF()`` commands can be removed. To create and access - messages from Python the ``message2`` package is now used. - - Update the ``#include`` statement and add the ``struct`` statement to read - - .. code:: cpp - - %include "architecture/msgPayloadDefC/ModuleMsgPayload.h" - struct ModuleMsg_C; - - Any custom Swig'd interfaces to access message content, such as - - .. code:: cpp - - ARRAYASLIST(FSWdeviceAvailability) - - should be removed from the ``module.i`` file and moved to ``src/architecture/messaging/messaging.i`` - file instead. These interfaces can now be used by any module by importing ``messages2`` in the - Xmera python script. - - - If you want to create an array of output messages ``SomeMsg_C``, the array of messages must be swig'd to be - accessible from python. In the module ``*.i`` file, add this statement - - .. code:: cpp - - STRUCTASLIST(SomeMsg_C) - - - The location of ``swig_common_model`` has moved to ``architecture``. Thus, replace:: - - from Xmera.simulation.swig_common_model import * - - with:: - - from Xmera.architecture.swig_common_model import * - -#. Updating the ``module.rst`` documentation file: - - - In the table of module messages, update any message variable names that were changed - as well as the message definition from ``SomeFswMsgPayload`` to ``SomeMsgPayload``. - - If applicable, update the module msg I/O illustration - -Updating a C++ Module -^^^^^^^^^^^^^^^^^^^^^ - -#. Updating the ``module.h`` file: - - - Update the ``#include`` statement to read in a C message definition through - - .. code:: cpp - - #include "architecture/msgPayloadDefC/SomeMsgPayload.h" - - To include a C++ message definition use - - .. code:: cpp - - #include "architecture/msgPayloadDefCpp/SomeMsgPayload.h" - - - Replace the include statement for the old message system - - .. code:: cpp - - #include "architecture/messaging/system_messaging.h" - - with the include for the new message system - - .. code:: cpp - - #include "architecture/messaging/messaging.h" - - - Remove both the ``selfInit()`` and ``CrossInit()`` methods, they are longer used. If you initialized any code in these functions, move that code to the module ``reset()`` method. - - - For output messages, replace the ``std::string`` message name variable - ``moduleOutMsgName`` and associated - ``int_32t`` message ID variable ``moduleOutMsgId`` with the ``public`` variable: - - .. code:: cpp - - Message moduleOutMsg; //!< sensor output message - - This creates an instance of the output message object that is contained within this module. - - - For input messages, replace the ``std::string`` message name variable - ``moduleInMsgName`` and associated - ``int_32t`` message ID variable ``moduleInMsgId`` with the ``public`` functor: - - .. code:: cpp - - ReadFunctor moduleInMsg; //!< sensor input message - - - It is possible to create a vector of output message pointers of type ``SomeMsgPayload`` using - - .. code:: cpp - - std::vector*> descriptionOutMsgs; - - - Similarly, you can create a vector of input message reader objects of type ``SomeMsgPayload`` - using the following statement. Note that you can directly create message reader instances, - and not pointers to such objects as with a vector of output messages. - - .. code:: cpp - - std::vector> descriptionInMsgs; - -#. Updating the ``module.cpp`` file: - - - There is no need for additional code to create an output connector. Thus, delete old message - creation code such as: - - .. code:: cpp - - this->moduleOutMsgId = SystemMessaging::GetInstance()->CreateNewMessage(this->moduleOutMsgName, - sizeof(ModuleSimMsg), - this->numOutMsgBuffers, - "ModuleSimMsg", this->moduleID); - - The new message object is automatically created through the above process in the ``module.h`` file. - In fact, deleted the ``selfInit()`` method as it is no longer needed with C++ modules. The output - message object automatically connect to themselves in their constructors. Any other code in - the ``selfInit()`` method should be moved to the ``reset()`` method. - - - If a ``std::vector`` of output message pointers of type ``SomeMsgPayload`` was created in the module ``*.h`` file - then these message objects must be created dynamically in the ``*.cpp`` code using - - .. code:: cpp - - Message *msg; - msg = new Message; - this->descriptionOutMsgs.push_back(msg); - - Don't forget to delete these message allocation in the module deconstructor. - - - If you have a ``std::vector`` of input message objects, these are typically provided - to the BSK module in Python through - a support function. For example, consider the case where the module has a vector of planet state input messages - that can be configured. The method ``addPlanet()`` then receives the message object pointer as shown below. - Next, the vector ``planetInMsgs`` must have a reader to the provided message object added. The message - method ``.addSubscriber()`` returns a reader object, essentially an input message linked to this output - message. The code below assumes the module also has a ``std::vector`` of the planet state payload structure - to act as the input buffer variables. This ``addPlanet`` routine below creates such buffer variables and adds - them to the ``planetMsgData`` vector each time a planet is added. - - .. code:: cpp - - void BskModuleName::addPlanet(Message *planetSpiceMsg) - { - /* add a message reader to the vector of input messages */ - this->planetInMsgs.push_back(planetSpiceMsg->addSubscriber()); - - /* expand the planet state input buffer vector */ - SpicePlanetStateMsgPayload plMsg; - this->planetMsgData.push_back(plMsg); - } - - - - To check is an output message has been connected to, check the value of ``this->moduleOutMsg.isLinked()`` - - - - To subscribe to an input message, this is now accomplished in the Xmera Python script - where the message to module connections are setup now. Thus, delete code such as this: - - .. code:: cpp - - this->moduleInMsgID = SystemMessaging::GetInstance()->subscribeToMessage(this->moduleInMsgName, - sizeof(ModuleFswMsg), moduleID); - - Remove the ``CrossInit()`` method, it is longer used. If you initialized any code in this method, - move that code to the module ``reset()`` method. - - - To read an input message, replace old code such as: - - .. code:: cpp - - InputFswMsg moduleInMsgBuffer; - memset(&moduleInMsgBuffer, 0x0, sizeof(InputFswMsg)); - this->moduleInMsg = - SystemMessaging::GetInstance()->ReadMessage(this->moduleInMsgID, &LocalHeader, - sizeof(InputFswMsg), - reinterpret_cast (&(moduleInMsgBuffer)), - moduleID); - - with this new code: - - .. code:: cpp - - InputMsgPayload moduleInMsgBuffer; - moduleInMsgBuffer = this->moduleInMsg(); - - Take a moment to marvel at the simplicity of this message reading! - - - To check is an input message has been connected to, check the value of ``this->moduleInMsg.isLinked()`` - - To check if a message has ever been written to, check the value of ``this->moduleInMsg.isWritten()`` - - To get the time when a message was written, use ``this->moduleInMsg.timeWritten()`` - - To get the ID of the module who wrote the message, use ``this->moduleInMsg.moduleID()`` - - - To zero a local message structure variable ``someMsgBuffer`` of type ``SomeMsgPayload``, remove - the use of ``memset()`` and use the C++ default initializer instead: - - .. code:: cpp - - SomeMsgPayload someMsgBuffer{}; - - - To write to an output message, replace this old code: - - .. code:: cpp - - SystemMessaging::GetInstance()->WriteMessage(this->moduleOutMsgId, clockTime, sizeof(OutputSimMsg), - reinterpret_cast (&outMsgBuffer), this->moduleID); - - with this new code: - - .. code:: cpp - - this->moduleOutMsg.write(&outMsgBuffer, this->moduleID, clockTime); - - Again, stop and marvel. - -#. Updating the ``module.i`` file: - - - The location of ``swig_common_model`` has moved to ``architecture``. Thus, replace:: - - from Xmera.simulation.swig_common_model import * - - with:: - - from Xmera.architecture.swig_common_model import * - - - In the ``GEN_SIZEOF()`` commands used to be used to get the size of a message in Python. This is no longer - required with the new message system. Thus, these ``GEN_SIZEOF()`` commands can be removed. To create and access - messages from Python the ``message2`` package is now used. - - - Update the C message definition include statement from - - .. code:: cpp - - %include "simMessages/OutputSimMsg.h" - - to use the new common message folder location - - .. code:: cpp - - %include "architecture/msgPayloadDefC/OutputMsgPayload.h" - struct OutputMsg_C; - - If including a C++ message payload definition, then only use: - - .. code:: cpp - - %include "architecture/msgPayloadDefCpp/OutputMsgPayload.h" - - - Any custom Swig'd interfaces to access message content, such as - - .. code:: cpp - - %template(RWConfigVector) vector; - - should be removed the ``module.i`` file and moved to ``src/architecture/messaging/messaging.i`` - file instead. These interfaces can now be used by any module by importing ``messaging`` in the - Xmera python script. - - - To create the swig interface to a vector of output message pointers of type ``SomeMsgPayload``, - near the bottom of the ``messaging.i`` file add this line:: - - %template(SomeOutMsgsVector) std::vector*>; - -#. Updating the ``module.rst`` documentation file: - - - In the table of module messages, update any message variable names that were changed - as well as the message definition from ``SomeFswMsgPayload`` to ``SomeMsgPayload``. - - If applicable, update the module msg I/O illustration - - If there are links to message types in the source method descriptions, update these - to use the new message payload declaration. - - -.. raw:: html - - diff --git a/docs/source/developer/migrating-to-python3.rst b/docs/source/developer/migrating-to-python3.rst deleted file mode 100644 index 39c65c5ec..000000000 --- a/docs/source/developer/migrating-to-python3.rst +++ /dev/null @@ -1,95 +0,0 @@ - -.. _migrating-to-python3: - -Migrating BSK Scripts to Python 3 -================================= - -With release Xmera v0.8.x onward the software framework now supports using Python 3. The purpose of this document is to illustrate how to -migrate Python 2 BSK scripts such that they will function in both Python -3 and Python 2. For the time being Python 2 is still supported as a -depreciated functionality. But, python scripts committed to Xmera -should be written such that they support Python 3 and 2 for now. This -document serves as compilation of BSK common syntactical adjustments -needed to use Python 3. It is not a comprehensive list of the -differences between Python 2 and Python 3. - -Dividing Scalars ----------------- - -Python 2 and 3 treat the devide operator ``/`` differently if two -integers operated on. Thus:: - - a = 3/2 - -resulted in an integer value of 1 in Python 2, but yields a float value -of 1.5 in Python 3. To get the same result in Python 3 and 2, you can -use either of the following options which work in both version of -Python:: - - a = 3//2 - a = 3./2 - -Without modification the user will see an error in Python 3 complaining about an unsupported type conversion:: - - File "/Users/hp/Documents/Research/Xmera/dist3/Xmera/simulation/sim_model/sim_model.py", line 4351, in logThisMessage - return _sim_model.SimModel_logThisMessage(self, messageName, messagePeriod) - NotImplementedError: Wrong number or type of arguments for overloaded function 'SimModel_logThisMessage'. - Possible C/C++ prototypes are: - SimModel::logThisMessage(std::string,uint64_t) - SimModel::logThisMessage(std::string) - -Returning Lists Instead of Iterables ------------------------------------- - -Python 3 removed ``iteritems()`` method. The same functionality can be achieved in both Python 2 and 3 with ``items()``. - -Range, Map, Zip ---------------- - -In Python 2 range() returns a list, while in Python 3 it returns an -iterable object. To preserve functionality, cast as a list:: - - list(range(x)) - -Print ------ - -Print is treated as a statement in Python 2 and strictly a function in Python 3. For both 3 and 2:: - - print(x) - -A sample warning is:: - - File "scenarioAttitudeFeedbackRW.py", line 715 - print dataUsReq - ^ - SyntaxError: Missing parentheses in call to 'print'. Did you mean print(dataUsReq)? - -Strings -------- - -External python packages will give warnings in ``pytest`` if -python strings include ``\x`` (raw-latex escape sequences) where x is not a pythonic valid escape character. These warnings did not appear using Python 2, when using strings as input for latex or for other text processing, they should be made a raw string by appending an r:: - - r"..." - -A sample warning is:: - - /Users/hp/Documents/Research/Xmera/src/tests/testScripts/../scenarios/scenarioAttitudeFeedbackRW.py:91: DeprecationWarning: invalid escape sequence \o - label='$\omega_{BR,' + str(idx) + '}$') - - -Pyswice Imports ------------------ -Changes to BSK module importing has changed the -pyswice importing convention to be completely explicit: - -From:: - - from Xmera import pyswice - pyswice.spkRead(...) - -To:: - - from Xmera.pyswice.pyswice_spk_utilities import spkRead - spkRead(...) diff --git a/docs/source/developer/module-checklist.rst b/docs/source/developer/module-checklist.rst index 8b439da27..5e8d43ab6 100644 --- a/docs/source/developer/module-checklist.rst +++ b/docs/source/developer/module-checklist.rst @@ -17,13 +17,13 @@ Building Xmera and Testing - Do a clean build of Xmera and make sure all code compiles as expected (see :ref:`FAQ ` on how to do a clean build) - From the project root directory, run ``python run_all_test.py`` and ensure all python and C/C++ tests are passing - as expected (see :ref:`install-optional-ackages` for info on installing and running ``pytest``) + as expected Style and Formatting -------------------- - Do the code variables satisfy the :ref:`Xmera code style - guidelines `? + guidelines `? - Are 4 spaces used instead of tabs? Module Programming @@ -80,14 +80,10 @@ Is a ``_UnitTest`` folder included that: Module Integrated Test ---------------------- -If an integrated test is provided as a ``test_XXX.py`` file. Does this test method have a complete description of what is being tested? The :ref:`test_cModuleTemplateParametrized.py ` file contains a template illustrating the expected information. Required sections include +If an integrated test is provided as a ``test_XXX.py`` file. Does this test method have a complete description of what is being tested? The ``test_cModuleTemplateParametrized.py`` file contains a template illustrating the expected information. Required sections include - Validation Test Description - Test Parameter Discussion - Description of variables being tested See the :ref:`FAQ ` on how to run generate an html validation report using ``pytest --report``. Note that it is ok to just run this report for the module being tested. - -Update Release Notes --------------------- -Update the :ref:`xmera-release-notes` at ``/docs/source/Support/User/release-notes.rst`` to include information about the new features being added. diff --git a/docs/source/install/linux-development-environment.rst b/docs/source/install/linux-development-environment.rst index 191e73916..d61ad821c 100644 --- a/docs/source/install/linux-development-environment.rst +++ b/docs/source/install/linux-development-environment.rst @@ -104,16 +104,17 @@ When all the prerequisite installations are complete, the project can be built a cd src cmake --preset base - cmake --build ../dist3 - cmake --install ../dist3 - pip install -e .. + cmake --build ../build --parallel + CMAKE_INSTALL_MODE=REL_SYMLINK_OR_COPY cmake --install ../build --prefix ../dist + pip install -e . -The project defines three CMake presets; +The project defines four CMake presets; -- base - Debug build profile with visualization dependencies -- full - Everything in "base" with OpNav dependencies -- ci-test - Everything in "full" with Release build profile. Simulation execution is faster with a Release build +- base - Debug build profile +- ci-test - Inherits from "base" with a Release build profile. Simulation execution is faster with a Release build profile. +- fuzz-smoke-test - Inherits from "ci-test" with fuzz tests enabled +- fuzz-test - Inherits from "fuzz-smoke-test" with fuzzing mode enabled To view the complete definition of these presets see the presets file in `src/CMakePresets.json`. @@ -127,13 +128,13 @@ To clean a build .. code-block:: console - cmake --build ../dist3 --target clean + cmake --build ../build --target clean To clean and then build .. code-block:: console - cmake --build ../dist3 --clean-first + cmake --build ../build --clean-first To test your setup you can run one of the :ref:`examples` diff --git a/docs/source/install/macos-development-environment.rst b/docs/source/install/macos-development-environment.rst index 6c25fec01..efa9a3e51 100644 --- a/docs/source/install/macos-development-environment.rst +++ b/docs/source/install/macos-development-environment.rst @@ -135,16 +135,17 @@ When all the prerequisite installations are complete, the project can be built a cd src cmake --preset base - cmake --build ../dist3 - cmake --install ../dist3 - pip install -e .. + cmake --build ../build --parallel + CMAKE_INSTALL_MODE=REL_SYMLINK_OR_COPY cmake --install ../build --prefix ../dist + pip install -e . -The project defines three CMake presets; +The project defines four CMake presets; -- base - Debug build profile with visualization dependencies -- full - Everything in "base" with OpNav dependencies -- ci-test - Everything in "full" with Release build profile. Simulation execution is faster with a Release build +- base - Debug build profile +- ci-test - Inherits from "base" with a Release build profile. Simulation execution is faster with a Release build profile. +- fuzz-smoke-test - Inherits from "ci-test" with fuzz tests enabled +- fuzz-test - Inherits from "fuzz-smoke-test" with fuzzing mode enabled To view the complete definition of these presets see the presets file in `src/CMakePresets.json`. @@ -158,13 +159,13 @@ To clean a build .. code-block:: console - cmake --build ../dist3 --target clean + cmake --build ../build --target clean To clean and then build .. code-block:: console - cmake --build ../dist3 --clean-first + cmake --build ../build --clean-first To test your setup you can run one of the :ref:`examples` diff --git a/docs/source/install/third-party-modules.rst b/docs/source/install/third-party-modules.rst index c616aad13..517238ade 100644 --- a/docs/source/install/third-party-modules.rst +++ b/docs/source/install/third-party-modules.rst @@ -40,7 +40,7 @@ Then add the symlinked path to ``XMERA_MODULE_ROOTS`` at configure time: -DXMERA_MODULE_ROOTS="${XMERA_MODULE_ROOTS};${sourceDir}/externalModules/" Or, more conveniently, create a user preset in ``src/CMakeUserPresets.json`` -(see :ref:`cmake-parameters` for details): +(see :ref:`CMake Build ` for details): .. code-block:: json @@ -80,7 +80,7 @@ The external module inclusion follows a strict directory structure resembling th A single folder contains all the custom Xmera modules and message definitions in a specific sub-folder structure shown below. -:: +.. code-block:: none custom-modules ├── externalModules @@ -137,6 +137,8 @@ Frequently Asked Questions #. How do I import these custom modules when I write a Xmera python simulation script? - The custom Xmera modules are built into a ``xmera.externalModules`` package. For example, to load a module - called ``customCppModule``, use:: + called ``customCppModule``, use: + +.. code-block:: python from xmera.externalModules import customCppModule diff --git a/docs/source/learn/xmera-principles/xmeraPrinciples-1.rst b/docs/source/learn/xmera-principles/xmeraPrinciples-1.rst index 708f4de00..c341ba4dc 100644 --- a/docs/source/learn/xmera-principles/xmeraPrinciples-1.rst +++ b/docs/source/learn/xmera-principles/xmeraPrinciples-1.rst @@ -1,7 +1,3 @@ -.. raw:: html - - - .. _xmeraPrinciples-1: Xmera Process and Task Creation diff --git a/docs/source/learn/xmera-principles/xmeraPrinciples-2.rst b/docs/source/learn/xmera-principles/xmeraPrinciples-2.rst index 0bc452529..80f6396fe 100644 --- a/docs/source/learn/xmera-principles/xmeraPrinciples-2.rst +++ b/docs/source/learn/xmera-principles/xmeraPrinciples-2.rst @@ -1,7 +1,3 @@ -.. raw:: html - - - .. _xmeraPrinciples-2: Adding Xmera Modules diff --git a/docs/source/learn/xmera-principles/xmeraPrinciples-2b.rst b/docs/source/learn/xmera-principles/xmeraPrinciples-2b.rst index 311689ca4..ad984a213 100644 --- a/docs/source/learn/xmera-principles/xmeraPrinciples-2b.rst +++ b/docs/source/learn/xmera-principles/xmeraPrinciples-2b.rst @@ -10,7 +10,7 @@ Seeing the Order of Process, Task and Module Execution Now that you have learned how to add and prioritize processes with task lists, as well as assign Xmera modules to the task for an ordered execution, it is nice to be able to see how the simulation is setup. -The :ref:`SimulationBaseClass` defines a method ``ShowExecutionOrder`` which will print to the terminal window +The ``SimulationBaseClass`` defines a method ``ShowExecutionOrder`` which will print to the terminal window the process names and priorties as they are setup to be executed. For each process you will see the order with which the tasks will be called, and the order of task modules that will be executed. This is very handy to quickly validate that the simulation is setup as desired. diff --git a/docs/source/learn/xmera-principles/xmeraPrinciples-3.rst b/docs/source/learn/xmera-principles/xmeraPrinciples-3.rst index 1a5d9edbe..8a7930193 100644 --- a/docs/source/learn/xmera-principles/xmeraPrinciples-3.rst +++ b/docs/source/learn/xmera-principles/xmeraPrinciples-3.rst @@ -1,8 +1,3 @@ -.. raw:: html - - - - .. _xmeraPrinciples-3: Connecting Messages diff --git a/docs/source/learn/xmera-principles/xmeraPrinciples-5.rst b/docs/source/learn/xmera-principles/xmeraPrinciples-5.rst index db4944b3b..04355901c 100644 --- a/docs/source/learn/xmera-principles/xmeraPrinciples-5.rst +++ b/docs/source/learn/xmera-principles/xmeraPrinciples-5.rst @@ -1,9 +1,3 @@ -.. raw:: html - - - .. _xmeraPrinciples-5: Creating Stand-Alone Messages diff --git a/docs/source/learn/xmera-principles/xmeraPrinciples-7.rst b/docs/source/learn/xmera-principles/xmeraPrinciples-7.rst index 45a6e4acf..0f1ec7ed2 100644 --- a/docs/source/learn/xmera-principles/xmeraPrinciples-7.rst +++ b/docs/source/learn/xmera-principles/xmeraPrinciples-7.rst @@ -3,10 +3,6 @@ Advanced: Redirecting Module Output to Stand-Alone Message ========================================================== -.. raw:: html - - - .. sidebar:: Source Code The python code shown below can be downloaded :download:`here `. diff --git a/docs/source/learn/xmera-principles/xmeraPrinciples-8.rst b/docs/source/learn/xmera-principles/xmeraPrinciples-8.rst index 52548c589..203a1cf69 100644 --- a/docs/source/learn/xmera-principles/xmeraPrinciples-8.rst +++ b/docs/source/learn/xmera-principles/xmeraPrinciples-8.rst @@ -29,7 +29,7 @@ both tasks are enabled, as both sets of modules are executed. To disable **all** tasks within a process, use the ``disableTasks()`` method on the process variable. The script executes another simulation step and prints output before and after to confirm that no tasks are running when they are disabled. -To re-enable a specific task, use the :ref:`SimulationBaseClass` method ``enableTask(name)``. The argument is the name of +To re-enable a specific task, use the ``SimulationBaseClass`` method ``enableTask(name)``. The argument is the name of the task you wish to enable. After another simulation step, the output confirms that the enabled task's modules are once again executed. diff --git a/docs/source/learn/xmera-principles/xmeraPrinciples-9.rst b/docs/source/learn/xmera-principles/xmeraPrinciples-9.rst index f39f02995..cbe89a21a 100644 --- a/docs/source/learn/xmera-principles/xmeraPrinciples-9.rst +++ b/docs/source/learn/xmera-principles/xmeraPrinciples-9.rst @@ -7,7 +7,7 @@ the ``DynamicObject`` class. This means they still have the regular Xmera ``res ``updateState()`` methods, but they also have a state machine and integrator build in as these modules have to integrate internal ordinate differential equations (ODEs). -Xmera modules such as :ref:`spacecraft` and :ref:`spacecraftSystem` inherit from the ``DynamicObject`` class. These +Xmera modules such as :ref:`spacecraft` and ``spacecraftSystem`` inherit from the ``DynamicObject`` class. These modules include the standard ``reset()`` and ``updateState()`` methods, but also incorporate a built-in state machine and numerical integrator to solve internal ordinary differential equations (ODEs). diff --git a/docs/source/releases/index.rst b/docs/source/releases/index.rst index 81257002c..94c31e0c7 100644 --- a/docs/source/releases/index.rst +++ b/docs/source/releases/index.rst @@ -9,5 +9,4 @@ as how to code up C or C++ Xmera modules. .. toctree:: :maxdepth: 2 - xmera-release-notes xmera-known-issues diff --git a/docs/source/releases/xmera-known-issues.rst b/docs/source/releases/xmera-known-issues.rst index 4a08557e4..761479005 100644 --- a/docs/source/releases/xmera-known-issues.rst +++ b/docs/source/releases/xmera-known-issues.rst @@ -14,7 +14,7 @@ Version |release| Version 2.3.0 ------------- -- A bug was introduced at 2.2.1 (2dc0a35) to the :ref:`SimulationBaseClass` `AddModelToTask` function when it was +- A bug was introduced at 2.2.1 (2dc0a35) to the ``SimulationBaseClass`` `AddModelToTask` function when it was refactored to use the updated module variable logging. The bug manifests as no data being logged for a variable when there are more than one task, a module in each task, and the variable being logged is from a module assigned to a task added to a process after the first task has been added to a process. @@ -65,7 +65,7 @@ Version 2.1.5 The code compiles, but auto-completion etc. doesn't work in that module. - :ref:`hingedRigidBodyStateEffector` and :ref:`dualHingedRigidBodyStateEffector` module inertial state outputs are relative to the central gravity body, not the inertial frame. This is now corrected. -- Adding an instrument camera to :ref:`vizInterface` has changed. See :ref:`vizardSettings` on how +- Adding an instrument camera to :ref:`vizInterface` has changed. See ``vizardSettings`` on how to use the new method ``addCamMsgToModule()``. Version 2.1.4 @@ -73,7 +73,7 @@ Version 2.1.4 - In Xcode, when editing ``vizInterface.c/h`` files, the protobuffer library is not properly found when opNav is included. The code compiles, but auto-completion etc. doesn't work in that module. -- prior version had a bug in computer the latitude in ``PCPF2LLA()`` inside :ref:`geodeticConversion`. This is used +- prior version had a bug in computer the latitude in ``PCPF2LLA()`` inside ``geodeticConversion``. This is used in the ``specifyLocationPCPF()`` method inside :ref:`groundLocation`, and in :ref:`msisAtmosphere` and :ref:`albedo`. - :ref:`coarsesunsensor` now receives in ``sensorList`` a list of CSS configuration state pointers, not @@ -245,11 +245,11 @@ Version 1.8.4 $ conan remote add conan-community https://api.bintray.com/conan/conan-community/conan $ conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan -- If running Windows the path to the Xmera library destination folder must be set, see :ref:`installWindows`. +- If running Windows the path to the Xmera library destination folder must be set. - On Linux and Windows the ``vizInterface`` and all ``opNav`` related modules is not properly linking. Thus, all associated modules, including saving to Vizard binaries, is not working in this version. - If running Windows, be sure to use ``pip install conan`` to get conan, and don't download the binary installer, - see :ref:`installWindows`. The binary installer causes several issues with this new build system in that + see the Windows install instructions. The binary installer causes several issues with this new build system in that it contains its own copy of Python, and thus checking for required python packages does work. - The new build system provides many speed improvements in doing a clean or partial build, but some small changes are required to update BSK python simulation scripts to be compatible with the new build system. @@ -371,7 +371,7 @@ Version 1.7.3 - WINDOWS ONLY: Windows users cannot currently run pytest directly on Xmera ``src/`` directory (there will be non-resolved python path issues that will result in erroneous ImportErrors). Instead, to verify proper installation of Xmera, windows users must enter the specific subdirectory they are attempting to test, only then to run pytest. This should result in appropriate behavior. Right now there is no known solution to this issue. - Here the reaction wheel dynamics have been modified such that the RW state output message is no longer hard-coded to ``rw_config_0_data``, etc. Rather, now the ``modelTag`` string is pre-pended to make this output msg name unique with. Any scripts that is logging this RW state message will have to be updated. The reason for this change is to allow multiple spacecraft to have RW devices and unique RW state messages. - There was an issue doing a clean compile using Python 2 which is addressed in the next version -- :ref:`test_reactionWheelStateEffector_integrated` didn't run on Python 2, this is fixed in the next version. +- ``test_reactionWheelStateEffector_integrated`` didn't run on Python 2, this is fixed in the next version. **Version 1.4.2** diff --git a/docs/source/releases/xmera-release-notes.rst b/docs/source/releases/xmera-release-notes.rst deleted file mode 100644 index ad64d84f6..000000000 --- a/docs/source/releases/xmera-release-notes.rst +++ /dev/null @@ -1,4060 +0,0 @@ -.. _xmera-release-notes: - -Xmera Release Notes -====================== - -.. sidebar:: In Progress Features - - - support a way to do thread-safe messaging - - automated documentation build system when code is pushed to the repo - - -Version |release| ------------------ -- Removed the depreciated manner of creating python modules - - -Version 2.3.0 (April 5, 2024) ------------------------------ -- Added optional facet articulation to the :ref:`facetSRPDynamicEffector` module. -- Fixed a bug where the legacy variable logging API would either, not log at all or log at a rate different to the - requested rate. -- Fixed a python version checking bug that prevented Xmera from compiling on Windows -- Created a new example scenario :ref:`scenarioHaloOrbit` demonstrating a near-Halo orbit simulation -- Updated versioning to better follow the `semantic versioning `_ standard, in the format - ``MAJOR.MINOR.PATCH``. Releases will increment the minor version number, while pull requests into develop will - automatically increment the patch number. This allows users to reference/require specific versions of Xmera - outside of the release cycle. - Online documentation is only built for the ``MAJOR.MINOR.0`` releases -- updated plotting of ``opNav`` example scenarios to work again with latest version of ``matplotlib`` -- fixed a slew of compiler warnings when compiling with Xcode 15 -- Refactored the ``PrescribedTransMsgPayload`` message by renaming the message to - :ref:`LinearTranslationRigidBodyMsgPayload` and renaming the message variables from ``scalarPos`` and ``scalarVel`` to - ``rho`` and ``rhoDot`` -- Deprecated the :ref:`prescribedMotionMsgPayload` message and replaced with two separate - :ref:`prescribedTranslationMsgPayload` and :ref:`prescribedRotationMsgPayload` messages. -- added support for the new ``swig`` 4.2 version -- updated the Windows build to compile properly with ``opNav`` flag set to true. A - ``opencv`` related flag had to be updated. -- added supoport for Vizard 2.1.6 -- Created a :ref:`prescribedLinearTranslation` dynamics module to profile prescribed linear translation for a - secondary rigid body connected to the spacecraft hub. This new module deprecates the ``prescribedTrans`` module. - To simulate the translation, this module must be connected to the :ref:`prescribedMotionStateEffector` - dynamics module. -- Created a :ref:`prescribedRotation1DOF` dynamics module to profile a prescribed 1 DOF rotation for a secondary - rigid body connected to the spacecraft hub. This new module deprecates the ``prescribedRot1DOF`` fsw module. - To simulate the rotation, this module must be connected to the :ref:`prescribedMotionStateEffector` dynamics module. -- Created a new example scenario :ref:`scenarioDeployingSolarArrays` demonstrating how to simulate hub-relative - multi-body prescribed motion. -- The fuel tank module is refactored to remove the limitation of a only being able to have a single instance of a - specific tank model type. -- Created a :ref:`singleAxisProfiler` simulation module to profile 1 DOF rotational prescribed motion about a - single hub-fixed axis. -- Added support for Vizard 2.1.6.1 -- Updated :ref:`MtbEffector` to include missing swig interface file for a message definition and corrected - message table in the module documentation. -- Added smoothed bang-bang and smoothed bang-coast-bang profiler options to the :ref:`prescribedLinearTranslation` - simulation module. Note that the optional module variable ``coastOptionRampDuration`` has been renamed to - ``coastOptionBangDuration``. The setter and getter methods for this variable are renamed to reflect this change as - ``setCoastOptionBangDuration()`` and ``getCoastOptionBangDuration()``, respectively. See the module documentation - for the current usage of this parameter and these associated methods. -- Added a new commanded linear force array :ref:`LinearTranslationRigidBodyMsgPayload`. -- Added a new single-axis translating effector :ref:`linearTranslationOneDOFStateEffector`. -- Added smoothed bang-bang and smoothed bang-coast-bang profiler options to the :ref:`prescribedRotation1DOF` - simulation module. Note that the optional module variable ``coastOptionRampDuration`` has been renamed to - ``coastOptionBangDuration``. The setter and getter methods for this variable are renamed to reflect this change as - ``setCoastOptionBangDuration()`` and ``getCoastOptionBangDuration()``, respectively. See the module documentation - for the current usage of this parameter and these associated methods. - -Version 2.2.1 (Dec. 22, 2023) ------------------------------ -- Created a new example scenario :ref:`scenarioSatelliteConstellation` demonstrating setup of a Walker-Delta constellation -- Created a new :ref:`pinholeCamera` module to support generation of landmarks-based measurements around a - small body. -- Corrected a memory leak in the ``swig`` access to standard vectors inside messages. -- A new integrated example script :ref:`scenarioSmallBodyLandmarks` demonstrates the use of the pinhole camera module -- Created a new example scenario :ref:`scenarioSpinningBodiesTwoDOF` that showcases the different capabilities of the - :ref:`spinningBodyTwoDOFStateEffector` module. -- Corrected an error with :ref:`thrusterStateEffector` where if there are multiple instances of the - thruster state effector then the last effector will over-write all the state of the earlier thrusters. -- Corrected an error with :ref:`magnetometer` where the RNG seed was passed to the Gauss-Markov noise model within the - constructor and could therefore not be modified after creating the object. Furthermore, the noise model is now only - used if all three components of the standard deviation parameter are initialized to a positive value. -- Removed fswAuto and associated documentation, as the tool was outdated. -- Changed how C modules are wrapped as C++ classes. This makes handling C modules the same as C++ modules, - removing the need for "Config" and "Wrap" objects. Updated all scenarios and test files for this new syntax. - To convert prior script to use the new syntax, see :ref:`xmeraPrinciples-2` for the simple new - syntaxt to add C-modules. -- Modified :ref:`mrpFeedback` to enable the use of a modified control law, and added the integral control torque - feedback output message. -- Created :ref:`lambertSolver` module to solve Lambert's problem -- Created :ref:`lambertPlanner` module to write the :ref:`lambertProblemMsgPayload` Lambert problem setup message -- Created :ref:`lambertValidator` module to check if the solution from the :ref:`lambertSolver` module violates any - constraints before a Delta-V is commanded. -- Added :ref:`scenarioLambertSolver` scenario to illustrate the Lambert solver module package -- Created :ref:`flybyPoint` to provide hill point reference during a flyby, and a related :ref:`scenarioFlybyPoint`. -- Created :ref:`thrusterPlatformState` to map the thruster configuration information to body frame given the - time-varying platform states. -- Created :ref:`thrustCMEstimation` to perform online estimation of the CM using gimbaled thruster torque measurements. -- Resolved a crash, induced by uninitialized memory, in the Camera module. The crash was first seen on Ubuntu 22 with - gcc 9.5 -- Added :ref:`scenario_LambertGuidance` BSK-Sim scenario to illustrate the Lambert modules in different flight modes -- Added :ref:`scenario_ClosedLoopManeuver` BSK-Sim scenario to illustrate how a Delta-V maneuver can be performed using - thrusters -- Created :ref:`sepPoint` to compute the reference attitude during SEP Point thrusting, with thruster alignment as - first constraint, and interchangeable second and third constraint consisting in maximum sunlight incidence on the - solar arrays, and keep-in constraint of a body-fixed direction around the Sun direction. -- Implemented new syntax for variable logging. See :ref:`xmeraPrinciples-6`. -- Added :ref:`scenarioMomentumDumpingZeroNetForce` scenario to illustrate momentum dumping without exerting a net force - on the spacecraft. -- Xmera minimum Python version is now formally 3.8.x (checked by build files). Previously, it was indicated to be - 3.7.x yet in practice it was 3.8.x. -- Added a ``TotalAccumDV_CN_N`` field in :ref:`SCStatesMsgPayload` that saves the total accumulated velocity of the - spacecraft's center of mass in the inertial frame. - -.. warning:: - - SWIG files (``.i``) for modules should include ``%include "sys_model.i"`` instead of ``%include "sys_model.h"`` - to take advantage of the new module variable logging feature. - -- Added prescribed angle and angle rates to :ref:`spinningBodyOneDOFStateEffector` and :ref:`spinningBodyTwoDOFStateEffector` - modules. -- Created a :ref:`scanningInstrumentController`, similar to :ref:`simpleInstrumentController`, but which constantly checks if the attitude error - and angular rate (optional) are within the requirement limits and sends an imaging command to a :ref:`simpleInstrument`. -- Added a new scenario :ref:`scenarioHohmann` that performs a Hohmann transfer with attitude mode changes. - The basic attitude flight modes are implemented using the Xmera event system. -- updated conan support to latest ``1.xx`` version to provide support for macOS Sonoma -- updated macOS ``cspice`` library to be compiled with Xcode 15. This addresses some errors that appeared - when calling the prior pre-built ``cspice`` library. The new library is backwards compatible with - prior versions of Xcode. -- Fixed a bug in the conanfile where the ``stderr`` output from a ``subprocess.Popen`` call was being interpreted as an - error. Rather, the process return code (0 for success, and anything else for failure) indicates the success. -- The ``MAX_N_CSS_MEAS`` define is increased to 32 matching the maximum number of coarse sun sensors. -- Fixed bug in time to nano-seconds conversions in ``macros.py`` support file -- Created :ref:`thrusterPlatformState` to map the thruster configuration information to body frame given the time-varying platform states. -- Updated :ref:`thrusterPlatformReference` to add an input and output thruster config msg, and integral feedback term - which dumps steady-state momentum in case of uncertainties on the CM location. -- Created :ref:`thrustCMEstimation` to perform online estimation of the CM using gimbaled thruster torque measurements. -- Refactored ``GravityEffector``. Adding custom gravity models can now be done by subclassing ``GravityModel``. The - utility method ``useSphericalHarmonicsGravityModel`` has been added to planetary body objects, which makes the body - use spherical harmonics and loads them from a file with a single command. Similarly, the methods ``usePolyhedralGravityModel`` - and ``usePointMassGravityModel`` have been added. -- Fixed examples and tests to run even when Xmera is built with ``--vizInterface False``. -- Added a new method ``setDataBuffer()`` to :ref:`simpleStorageUnit` and :ref:`partitionedStorageUnit` to add or remove data from specified partitions. -- Refactored ``simIncludeGravBody``. The most notable change for users is that the commonly used line - ``scObject.gravField.gravBodies = spacecraft.GravBodyVector(list(gravFactory.gravBodies.values()))`` - can be replaced by ``gravFactory.addBodiesTo(scObject)`` (where ``scObject`` is a ``spacecraft.Spacecraft`` - or ``spacecraftSystem.SpacecraftSystem``, and ``gravFactory`` is a ``simIncludeGravBody.gravBodyFactory``) -- Added condition in :ref:`thrustCMEstimation` to avoid measurement updates when input ``attGuidInMsg`` has not been written. -- Added :ref:`scenarioSepMomentumManagement` to show how to use a dual-gimbaled electric thruster to perform contunuous - momentum management. -- Clarified documentation of the input variable ``FirstStart`` of the method ``CreateNewTask()``. -- Marked the method ``CreateNewTask()`` input variable ``InputDelay`` as depreciated. This variable - was never implemented and did nothing. -- Fixed terminal events to terminate at the time they are triggered instead of one timestep after. - - - -Version 2.2.0 (June 28, 2023) ------------------------------ -- Created new way to define Python modules by inheriting from ``Xmera.architecture.sysModel.SysModel``. - See pyModules for details. -- Added the ability to integrate the ODE's of two or more Xmera modules that are ``DynamicObject`` class - member at the same time. See :ref:`xmeraPrinciples-9` -- updated ZMQ version to 4.5.0. For 2-way communication with ``opNav`` modules talking to Vizard - then Vizard 2.1.5 or newer should be used. This also removes the need for the legacy bincrafters code repo. - Delete ``~/.conan`` folder if you run into ``conan`` issues. -- The Xmera project C++ version is advanced from C++11 to C++17 -- Disabled the following build options in the conan included OpenCV dependency; with_ffmpeg video frame encoding lib, - with_ade graph manipulations framework, with_tiff generate image in TIFF format, with_openexr generate image in EXR - format, with_quirc QR code lib. Users that have Xmera control the build of these modules through the External - Modules CMake integration will need to manual toggle these OpenCV build options. -- Updated :ref:`SmallBodyNavEKF` with several bug fixes. Removed spacecraft attitude estimation component. -- Bug fix made to :ref:`eclipse`: Saturn, Jupiter, Uranus, and Neptune radii were incorrectly being assigned the - radius of Mars. -- Added custom planet name to :ref:`eclipse` in case the user wants to use a body not contained within the module. -- Removed all instances of using ``unitTestSupport.np2EigenVectorXd()``, as this function is now unneeded. -- Created a :ref:`facetSRPDynamicEffector` dynamics module to calculate the B frame SRP force and torque acting on a - static spacecraft. -- fixed ``PCI2PCPF()`` and ``PCPF2PCI`` methods in :ref:`geodeticConversion` to use the correct DCM -- updated :ref:`geodeticConversion` to be able to account for planet ellipsoidal shape if polar radius is provided -- Google Test C/C++ testing framework added -- Created a :ref:`prescribedRot2DOF` fsw module to profile a prescribed 2 DOF rotational maneuver for a secondary rigid - body connected to the spacecraft hub. To simulate the maneuver, this module must be connected to the - :ref:`prescribedMotionStateEffector` dynamics module. -- Corrected default value of ``accuracyNanos`` in :ref:`simSynch` to be 0.01 seconds. -- Added a deprecation system for Xmera. For developers, see :ref:`deprecatingCode`. -- Changed the units of plasma flux in :ref:`dentonFluxModel` and :ref:`PlasmaFluxMsgPayload` from - [cm^-2 s^-1 sr^-2 eV^-1] to [m^-2 s^-1 sr^-2 eV^-1], because m^-2 is used more frequently in computations -- Fixed a bug in eclipse that caused potentially occluding bodies to be skipped if a prior body was closer to the sun - than the spacecraft -- fixed the time evaluation in :ref:`msisAtmosphere` -- Added an optional ``controllerStatus`` variable and ``deviceStatusInMsg`` message to the - :ref:`simpleInstrumentController` to match the functionality of the corresponding data and power modules -- Corrected tasks priorities in several scenarios and added checks in two modules to ensure that C MSG read errors are - not thrown -- Fixed bug where message struct members of bool python types are returned as empty dicts instead of array of boolsgit -- Refactored the :ref:`prescribedMotionStateEffector` dynamics module to vary the prescribed states across the dynamics - integration time step. -- The encryption build option for the project's conan zmq dependency is disabled because it is uneeded. -- Added an optional ``controllerStatus`` variable and ``deviceStatusInMsg`` message to the :ref:`simpleInstrumentController` to - match the functionality of the corresponding data and power modules -- Corrected tasks priorities in several scenarios and added checks in two modules to ensure that C MSG read errors are not thrown -- Reworked how integrators are implemented. New Runge-Kutta integrators may - now be added simply by specifying the relevant coefficients. -- Added a scenario that showcases differences between integrators. See :ref:`scenarioIntegratorsComparison` -- Updated :ref:`thrusterPlatformReference` to add an integral feedback term which dumps steady-state momentum in case of uncertainties on the CM location. - -Version 2.1.7 (March 24, 2023) ------------------------------- -- Fixed ``CMake/conan`` case sensitivty issue when compiling Xmera with ``opNav`` flag set to ``True`` on Linux platforms -- Created fsw :ref:`hingedRigidBodyPIDMotor` to compute the commanded torque to :ref:`spinningBodyOneDOFStateEffector` using a proportional-integral-derivative controller. -- Added :ref:`torqueScheduler` to combine two :ref:`ArrayMotorTorqueMsgPayload` into one and implement effector locking logic. -- Refactored how ``Custom.cmake`` files are included and how they are to be constructed. ``Custom.cmake`` files - should no longer include an include guard (e.g. ``if(BUILD_OPNAV) ... endif(BUILD_OPNAV)`` ). Rather, to add - optionally compile a module, its directory name should be added to a list in - ``src/cmake/bskTargetExcludeBuildOptions.cmake``. Most importantly, the build target is now accessible within the - a ``Custom.cmake`` file as ``${TARGET_NAME}``. This enables appropriate modularization of build target specific - includes, dependencies, and compiler flags. For an example of the implications of this refactor review the before - and after of the ``src/cmake/usingOpenCV.cmake`` file. -- updated :ref:`unitTestSupport` to create the file path in a platform agnostic manner -- Created a :ref:`sensorThermal` module to model the temperature of a sensor using radiative heat transfer -- Created a :ref:`tempMeasurement` module to add sensor noise/bias and fault capabilities to temperature readings -- Added a ``terminal`` flag to the event handlers that cause the simulation to terminate when triggered; demonstrated - use of flag in update to :ref:`scenarioDragDeorbit`. -- Created a :ref:`prescribedMotionStateEffector` dynamics module for appending rigid bodies with prescribed motion - to the spacecraft hub. -- Created a :ref:`prescribedRot1DOF` fsw module to profile a prescribed rotational maneuver for a secondary rigid body - connected to the spacecraft hub. To simulate the maneuver, this module must be connected to the - :ref:`prescribedMotionStateEffector` dynamics module. -- Created a :ref:`prescribedTrans` fsw module to profile a prescribed translational maneuver for a secondary rigid body - connected to the spacecraft hub. To simulate the maneuver, this module must be connected to the - :ref:`prescribedMotionStateEffector` dynamics module. -- Added :ref:`solarArrayReference` to compute the reference angle and angle rate for a rotating solar array. -- Update python dependency documentation and check to not use ``conan`` version 2.0.0 for now -- Changed the ``SpinningBodyStateEffector`` module name to :ref:`spinningBodyOneDOFStateEffector`. -- Added the ability to lock the axis on the :ref:`spinningBodyOneDOFStateEffector` module. -- Added two new unit tests to :ref:`spinningBodyOneDOFStateEffector`. -- Updated :ref:`magneticFieldWMM` to use the latest WMM coefficient file and evaluation software -- Added a :ref:`spinningBodyTwoDOFStateEffector` module that simulates a two-axis rotating rigid component. -- Created :ref:`oneAxisSolarArrayPoint` to generate the reference attitude for a spacecraft that needs to point a body-fixed - axis along an inertial direction while ensuring maximum power generation on the solar arrays -- Added a maximum power parameter ``maxPower`` to :ref:`reactionWheelStateEffector` for limiting supplied - power, independent of the modules in simulation/power. -- Added :ref:`thrusterPlatformReference` to align the dual-gimballed thruster with the system's center of mass, or at an offset thereof to perform momentum dumping. -- Improved reliability of opNav scenario communication between :ref:`vizInterface` and Vizard -- provide support or Vizard 2.1.4 features - - -Version 2.1.6 (Jan. 21, 2023) ------------------------------ -- Refactored :ref:`keplerianOrbit` to not depend on the ``gravityEffector`` class -- Updated Xmera install documentation to discuss accessing source code from GitHub.com -- Fixed an issue where attaching a thruster to a body different than the hub when using ``zeroBase`` would yield very large offsets. -- Added documentation in :ref:`xmeraPrinciples-4` on how to read the current message values -- Highlighted the challege of setting up a ``recorder`` on a re-directed message in :ref:`xmeraPrinciples-7` -- added the ability to add a ``recorder()`` to a C-wrapped module input message -- Fix an issue in in :ref:`magneticFieldWMM` where a fixed width array holding a file path would result in a cutoff - path when xmera is located in a directory path of greater than 100 characters. -- Updated the build system to use newer versions of ``eigen``, ``protobuf``, ``cppzmq`` - and ``opencv``. This corrects some build issues with new compilers. -- The ``linearAlgebra``, ``rigidBodyKinematics``, ``orbitalMotion`` were mistakenly exposed as part of the - :ref:`sim_model` module's API. They have been removed and the functions they provided are still found in - ``Xmera.utilities.orbitalMotion``, ``Xmera.architecture.linearAlgebra``, and - ``Xmera.architecture.rigidBodyKinematics``. -- Fixed an issued recording the ``timeWritten`` information of a C-wrapped message - with a ``recorder()`` module. -- Updated :ref:`pullCloneBSK` to ask the user to first install ``lfs`` before pulling a copy - of the Xmera repo due to some large files being stored in the GitHub large file storage - system. -- Updated :ref:`scenarioGroundLocationImaging` to properly save off the ground location - information for Vizard -- Added a new helper function to convert C arrays to ``Eigen::MRPd`` and vice-versa inside ``eigenSupport``. -- Updated ``SpinningBodyStateEffector`` to use the :ref:`HingedRigidBodyMsgPayload` output message type for compatibility with other modules -- Added the ability to set an inertial heading in the :ref:`boreAngCalc` module. Changed the internal module logic to use ``Eigen`` library variables and functions instead of C-style arrays and methods. -- Added support for Vizard v2.1.3 -- Updated :ref:`simpleInstrumentController` to provide the option to consider the angular velocity tracking error norm - when considering to take an image. - - -Version 2.1.5 (Dec. 13, 2022) ------------------------------ -- Made the external module custom message definitions work again with the - latest build system. -- Fixed the custom RW in :ref:`simIncludeRW` to store the information regarding ``u_min`` in the RW class. -- provide support for the swig 4.1 software -- Added the ability in both :ref:`thrusterDynamicEffector` and :ref:`thrusterStateEffector` to connect a thruster to a moving body different than the hub. -- The thrusters now have an additional variable called ``MaxSwirlTorque``. Useful for ion thrusters, it adds a torque about the thrust axis proportional to the current thrust factor. -- Added a torsional spring and damper to the ``SpinningBodyStateEffector`` module. -- Added support for having multiple Vizard instrument cameras setup in :ref:`vizInterface` - -.. warning:: - - The support for having multiple Vizard instrument cameras requires a change in :ref:`vizInterface`, - and thus breaks existing code that using direct Vizard communication. The - image output message is now a vector of output messages, and the ``cameraConfigBuffer`` class variable - can no longer be set directly. Rather, the camera configuration message should be added - using the ``viz.addCamMsgToModule()``, or the message can be created and added using the convenience method - ``vizSupport.createCameraConfigMsg()``. - -- Updated :ref:`hingedRigidBodyStateEffector` and :ref:`dualHingedRigidBodyStateEffector` such that - the effector inertial states are relative to the inertial frame of the simulation, not the - central body frame. -- Added ``color`` keyword support to the ``vizSupport.createCustomModel()`` method -- Updated :ref:`cppModules-4` to explain how now the swig interface to vectors of input/output messages - are now auto-generated when making Xmera project -- added documentation about creating and importing custom Unity addressable assets - in :ref:`vizardCustomUnityModels`. -- fixed :ref:`scenarioAttLocPoint` to display the Earth location and the associated cone - again in Vizard. Updated :ref:`vizardSettings` description of ``addLocation()`` method. -- Added experimental support to build Xmera on Linux with a computer using an ARM processor. -- Updated :ref:`CameraConfigMsgPayload` to support the Vizard flag ``updateCameraParameters`` which - allows the camera parameters to be updated live. -- Updated documentation to discuss downloading Xmera from GitHub - - -Version 2.1.4 (Oct. 1, 2022) ----------------------------- - -- revised how the build system swig's all the message objects. This leads to compile time improvements across all - platforms. In Linux in particular we are seeing a 2x reduction in compile time. These changes also reduce - the memory requirements when compiling. Note: The ``xmera.architecture.cMsgCInterfacePy`` content is - now included in ``xmera.architecture.messaging`` package. Prior scripts using ``cMsgCInterfacePy`` - still run as a link has been created. However, the use of ``cMsgCInterfacePy`` is depreciated and code - should be updated to using ``messaging`` instead. -- added new :ref:`hingedRigidBodyMotorSensor` for adding noise, bias, and discretization to panel state message -- added new :ref:`simpleVoltEstimator` to provide simulated voltage measurements of a neighboring space object -- added the ability to have a RW motor torque break slow down the wheel speed if saturated. The motor torque - is set to zero if it is trying to increase the wheel speed in saturation conditions. -- updated Windows install instructions about setting path variables -- enhanced Windows install instructions to highlight adding ``cmake`` binary to the command line path -- added new training videos to :ref:`scenario_BasicOrbit`, :ref:`scenario_FeedbackRW` to discuss how to - create class based Xmera simulations -- added new :ref:`groundMapping` for mapping points on the surface of a spherical body. -- added new :ref:`mappingInstrument` to pass along access from a vector of map points to a storage unit. -- updated :ref:`locationPointing` to allow for spacecraft targeting as well -- added new :ref:`scenarioGroundMapping` scenario to demonstrate the new mapping capabilities. -- added new :ref:`scenarioRendezVous` scenario illustrating a servicer approaching - a debris object and engage several flight modes. -- added new scenario :ref:`scenarioDragDeorbit` -- added new scenario :ref:`scenarioLagrangePointOrbit` -- added Vizard 2.1.1 support for spacecraft ellipsoid shapes, Unity camera parameters -- added support for the polynomial gravity model to :ref:`gravityEffector` -- updated the ``conanFile.py`` to fix configuration and building issues with the latest - version of python -- fixed issue computing latitude angle in ``PCPF2LLA()`` in :ref:`geodeticConversion`. This was used - in the helper method ``specifyLocationPCPF()`` method inside :ref:`groundLocation`, as well as - :ref:`msisAtmosphere` and :ref:`albedo`. -- fixed an issue in the RKF45 variable time step integrator where one of the constants had the wrong sign. -- added new :ref:`scenarioMomentumDumping` to illustrate how to perform momentum dumping using thrusters. -- updated :ref:`hingedRigidBodyStateEffector` to allow for an optional panel reference state input message -- added new :ref:`scenarioDeployingPanel` to demonstrate panel deployment using panel reference message -- added new :ref:`thrusterStateEffector` which is compatible with a variable time step integrator. Here - the thrust on-off command is passed through a first order low-pass filter to provide smooth on- and - off-ramping. -- added new attitude pointing scenario :ref:`scenarioAttitudeFeedback2T_stateEffTH` that uses - the new :ref:`thrusterStateEffector` -- added ability to simulate faults within :ref:`coarseSunSensor` module -- created a 1-DoF rotating rigid body class ``SpinningBodyStateEffector``. It is built in a general way to simulate - any effector with a single spinning axis. - - -Version 2.1.3 (May 25, 2022) ----------------------------- -- corrected how :ref:`planetEphemeris` computes the celestial body orientation -- corrected issue in Monte Carlo controller class where if a single run is called that fails, - this was not reported -- updated Xmera documentation CSS to work with the latest version of ``sphinx`` and ``breathe`` -- added new :ref:`tabularAtmosphere` to calculate atmospheric density using atmosphere tables -- created new :ref:`smallBodyNavUKF` to make an UKF filter for small body navigation -- created new example script :ref:`scenarioSmallBodyNavUKF` to demonstrate the use of :ref:`smallBodyNavUKF` -- added a function titled ``SpherePlot()`` that allows for plotting of charged spheres based - on the MSM model :ref:`msmForceTorque` -- created new :ref:`smallBodyWaypointFeedback` module for waypoint-to-waypoint control about a small body -- created new example script :ref:`scenarioSmallBodyFeedbackControl` to demonstrate the new module -- added :ref:`scenario_AddRWFault` to show how to use event handlers to add faults -- added :ref:`constrainedAttitudeManeuver` with MRP-cartesian-distance- and effort-based A* graph search algorithms -- added :ref:`scenarioAttitudeConstrainedManeuver` to illustrate how to use :ref:`constrainedAttitudeManeuver` -- added ``specifyLocationPCPF()`` method to :ref:`groundLocation` for specifying ground locations in planet-centered, - planet-fixed coordinates -- updated :ref:`spacecraftLocation` to handle cases where the closed approach point to - the planet is outside the spacecraft-spacecraft interval -- added new :ref:`scenarioAerocapture` which simulates an aerocapture scenario -- added new :ref:`hingedBodyLinearProfiler` to provide a panel deployment angular profile -- added new :ref:`hingedRigidBodyMotor` to provide panel motor torque control -- added new training videos to configureBuild, installOptionalPackages, :ref:`scenarioBasicOrbit`, - :ref:`scenarioOrbitManeuver`, :ref:`scenarioOrbitMultiBody`, :ref:`scenarioCustomGravBody` -- added support for Vizard 2.1 scripting - - -Version 2.1.2 (March 12, 2022) ------------------------------- -- enhanced :ref:`spiceInterface` to allow Spice spacecraft names to be setup to pull their - trajectory and attitude states from a spice kernel -- added :ref:`scenarioSpiceSpacecraft` to illustrate using Spice to specify the trajectory of a - spacecraft while leaving the attitude dynamics unprescribed. -- fixed a bug where using the generator flag to build on windows would skip a line in the conanfile.py that is crucial for building opNav. -- added :ref:`dentonFluxModel` to compute electron and ion fluxes for the GEO regime. -- fixed build issue with ``conan`` version 1.44 or newer -- fixed an issue doing a clean build of ``opNav`` mode where conan failed to install ``opencv/4.1.1`` - with the ``jasper`` dependency. -- enhanced ability to set the planet Spice frame in the gravity factory class -- new ability to set the Vizard celestial body name to be different from the Spice planet body name -- added support for ``pytest`` version 7.0.0 and higher -- updated how ``pytest`` is run to generate a resulting HTML report -- modified :ref:`msmForceTorque` to create an output message with the MSM charge values for each spacecraft -- added new :ref:`scenarioInertialSpiral` example scenario -- improved robustness of Xmera installation script -- provide support for Vizard 2.0.4 feature scripting -- added a new heliocentric mission simulation example using custom Spice spacecraft - trajectory file :ref:`scenarioHelioTransSpice` -- added a new planetary fly-by mission example using a custom Spice translational file and - attitude pointing modes :ref:`scenarioFlybySpice` -- added a new asteroid arrival mission example with attitude pointing modes :ref:`scenarioAsteroidArrival` -- added a new scenario :ref:`scenarioTwoChargedSC` illustrating how to apply the MSM spacecraft - charging model to a relative motion simulation - - -Version 2.1.1 (Dec. 15, 2021) ------------------------------ -- Updated ``OpNav`` mode dependency ``gettext`` to version 0.21 to allow BSK to be build on Windows - with ``OpNav`` support. -- created two new messages that contain the information regarding scheduled burns for orbit reconfiguration in - formation flying scenarios. See :ref:`ReconfigBurnInfoMsgPayload` and :ref:`ReconfigBurnArrayInfoMsgPayload`. -- the module :ref:`spacecraftReconfig` now outputs a message of type :ref:`ReconfigBurnArrayInfoMsgPayload`. - All internal calculation are also done using a buffer of this message type. -- Added the time standard library to include statements in atmosphereBase.h to fix a build issue found on windows. -- updated :ref:`spacecraft` to include an optional translational reference message to specify the trajectory -- Added a swig array-type ``ARRAYINTASLIST`` that fixes a double to int conversion error when building the - ``FSWdeviceAvailability`` message on windows. -- Updated dispersions.py to support functionality that was deprecated in python3.10. This change supports - python versions >=3.3. -- Updated the Windows build process to fix a static runtime library issue with ``vizInterface`` found - in older versions of visual studio. -- Added scripting support for Vizard 2.0.3 - -Version 2.1.0 (Nov. 13, 2021) ------------------------------ -- added BSpline function to ``utilities`` and related UnitTest. -- added kinematic relations between angular accelerations and second derivative of MRP set to - :ref:`rigidBodyKinematicsutilities` library -- updated the installation script to function with the latest ``conan`` program and the recent - ``conan`` repo changes. Note, you will have to delete the ``.conan`` folder in your home - directory to create a fresh copy of the software dependencies. -- added a Developer support page :ref:`debugging` -- fixed a memory leak with the Swig layer where an object was not released properly. Thanks go to - Stephen Ritter and Toney for tracking down this issue. -- added a new orbit maneuver example :ref:`scenarioJupiterArrival` -- made SWIG interface to the MRP derivative variable -- added two new variable time step integrators. See :ref:`svIntegratorRKF45` and :ref:`svIntegratorRKF78`. -- updated the state effector base class to also provide the current integration time step in addition to the - current time -- added new scenario :ref:`scenarioVariableTimeStepIntegrators` -- updated :ref:`scenarioIntegrators` to include the ``rkf45`` and ``rkf78`` options -- changed the way :ref:`spacecraftReconfig` gets the deputy's mass properties. It now receives that information - through a message of the type ``VehicleConfigMsgPayload`` instead of an internal variable. Relevant example - scripts have been updated. -- new tutorial example scenario script :ref:`scenarioTAMcomparison` -- new mass sensor that converts a ``simulation`` mass properties message to a ``FSW`` vehicle configuration message :ref:`simpleMassProps` -- added scripting support for Vizard 2.0.1 and 2.0.2 -- This release provides a new ability to run a single Xmera simulation in a multi-threaded manner. - The BSK processes can be spread across multiple threads. See :ref:`scenario_BasicOrbitMultiSat_MT` - for an example of how to use this. - -.. warning:: - - The BSK v2.1 multi-threading assumes all processes assigned to a thread can run independently - from processes in another thread. Further, cross thread message communication is not yet - thread safe! - - -Version 2.0.7 -------------- -- new :ref:`forceTorqueThrForceMapping` to map commanded forces and torques to a set of thrusters -- updated Vizard documentation on the setting flags ``orbitLinesOn`` and ``trueTrajectoryLinesOn`` -- added power and fuel tank modules to the :ref:`BSK_MultiSatDynamics` class. -- improved the DV calculation of the spacecraft state output message by integrating the gravitational acceleration - using the current integration scheme rather than using a first order approximation. -- updated install script to be able to have ``conan`` install ``opencv`` again. Something changed with the ``conan`` - repo that broke this. -- updated BSK install instructions on the M1 Apple Silicon platform as Basiliks can now run natively - - -Version 2.0.6 -------------- -- updated :ref:`vizInterface` to support Vizard 1.9.1 and the ability to visualize generic sensor types and - antenna communication status -- updated :ref:`ephemerisConverter` to also convert the planet orientation states, not just the - translational states -- added a :ref:`planetNav` module that adds noisy to planet ephemeris, similar to simpleNav. -- created a new device command status message :ref:`DeviceCmdMsgPayload` and updated :ref:`simpleInstrumentController`, - :ref:`simpleInstrument` and :ref:`spaceToGroundTransmitter` to make use of it. -- added :ref:`attRefCorrection` to adjust the reference attitude by a fixed rotation -- added :ref:`scenarioAttitudePrescribed` to illustrate how to prescribe the spacecraft orientation -- added new modules :ref:`mtbFeedforward`, :ref:`mtbMomentumManagementSimple`, :ref:`dipoleMapping` and - :ref:`torque2Dipole` which are using in combination to achieve MTB based RW momentum dumping. -- added a new magnetic RW momentum dumping example in :ref:`scenarioMtbMomentumManagementSimple` which illustrates - using the above new MTB related modules to change the momentum, as well as drive the nominal momentum to - a desired value using :ref:`rwNullSpace`. -- created a new architecture based on ``BskSim`` called ``MultiSatBskSim``. It exploits the new messaging system to create a simulation - with any number of spacecraft in a highly modular way. It allows for the addition of homogeneous or heterogeneous satellites without - having to hard code their properties into a single dynamics or FSW script. It will be a foundation to test the upcoming multithreading - capabilities of Xmera. -- added three example scenarios that showcase this new architecture. See :ref:`scenario_BasicOrbitMultiSat`, :ref:`scenario_AttGuidMultiSat` - and :ref:`scenario_StationKeepingMultiSat`. -- added a new FSW module :ref:`formationBarycenter`. It computes the barycenter's position and velocity of a swarm of satellites. This barycenter - can be either computed with cartesian coordinates (usual mass-weighted average), or using orbital elements weighted average. Will be useful - for spacecraft formations defined around the barycenter of the swarm and not a chief spacecraft. -- enhanced :ref:`locationPointing` to support the target input msg being either a location message or an - ephemeris message -- updated install notes to ensure Linux python3 developer libraries are installed, and to ensure that ``wheel`` - package is installed along with ``conan`` -- created :ref:`smallBodyNavEKF` to simulate autonomous navigation in proximity of a small body -- added a :ref:`AttRefMsgPayload` output message to the :ref:`locationPointing` module. -- added :ref:`cppModules-5` to the section on learning how to create BSK modules -- updated :ref:`locationPointing` to support 3D rate damping as an option - - -Version 2.0.5 -------------- -- fixed issue in :ref:`waypointReference` to interpolate between waypoint ``n`` and shadow set of - waypoint ``n+1`` when these are described by opposite MRP sets. Updated documentation and corrected - typos in :ref:`scenarioAttitudeConstraintViolation`. -- Added :ref:`hillStateConverter` and :ref:`hillToAttRef` modules for formation flight navigation and attitude-driven differential drag -- Added representative scenario :ref:`scenarioDragRendezvous` demonstrating attitude-driven differential drag formation flight -- Added new scenario :ref:`scenarioDragSensitivity` showing how to do a differential drag - spacecraft control sensitivity analysis -- updated :ref:`celestialTwoBodyPoint` to account for a case where the celestial objects are in opposite directions -- replaced ``acos()`` and ``asin()`` with ``safeAcos()`` and ``safeAsin()`` which ensure that arguments are - clipped to be within and including -1 and 1 -- updated :ref:`dataFileToViz` to allow the ``reset()`` method to be called multiple times. If a data file - was already opened, then it is closed before the next data file is opened. -- updated :ref:`groundLocation` to also output SEZ coordinates, as well as range, azimuth, elevation, south, east - and zenith coordinate rates. These coordinates are always computed regardless if a spacecraft is visible to the - target. Check the ``hasAccess`` message variable to see if the spacecraft is visible. -- updated the OpNav examples script to set a black sky background in the Vizard camera images -- added a new Python method ``isSubscribedTo()`` to query if the input and output messages between - two modules are connected -- updated :ref:`gravityEffector` documentation to properly pull in the RST documentation and link to the - PDF describing the gravity models -- updated ``setAllButCurrentEventActivity`` method in :ref:`SimulationBaseClass` to work with multiple satellites. We can now add an index at the - end of each event name that guarantees only events with the same index are affected. The ``useIndex`` flag must be set to ``True``. -- added new magnetic torque bar effector in :ref:`MtbEffector` -- added new FSW module to control the RW momentum using MTBs in :ref:`mtbMomentumManagement` -- new tutorial example script :ref:`scenarioMtbMomentumManagement` -- updated :ref:`rwNullSpace` to have an optional input message of desired RW speeds. These desired values default to - zero so the module retains the earlier behavior if this optional input message is not connected. -- added two lines in :ref:`waypointReference` to normalize the attitude quaternion that is read from file. - -Version 2.0.4 -------------- -- updated :ref:`spacecraft` ``reset()`` method to write all spacecraft and effector state output messages - with their initial values. This way these output messages are correct as already as calling the - ``InitializeSimulation()`` method. -- fixed an issue that could prevent ``.subscribeTo`` from a C++ to C wrapped message object to not function - properly. -- new :ref:`simpleInstrumentController` that sends an imaging command to a :ref:`simpleInstrument` if the attitude error - and access to a :ref:`groundLocation` module are within requirements. -- new :ref:`scenarioGroundLocationImaging` example script that demonstrates the aforementioned module integrated into a - full on-board data system. -- new :ref:`etSphericalControl` module that controls the relative motion of the Electrostatic Tug -- new :ref:`scenarioDebrisReorbitET` example script that demonstrates using the Electrostatic Tug and the - Multi-Sphere Method -- updated :ref:`groundLocation` to always compute the elevation, range and azimuth information, even if - the satellite does not have access. The output message variable ``hasAccess`` provides access information. -- added scripting support for Vizard 1.8.4 -- updated :ref:`scenarioGroundLocationImaging` to demonstrate the use of the - new ``vizSupport.createTargetLine()`` method - - - -Version 2.0.3 -------------- -- new integrated scenario in :ref:`scenarioAttitudeConstraintViolation`. Shows how to use the :ref:`boreAngCalc` to display keep-in and keep-out constraint violations while - performing slew maneuvers. -- new :ref:`locationPointing` module to do 2-axis attitude control which aligns a body-fixed vector to a - desired inertial location -- new :ref:`scenarioAttLocPoint` example script how to point a spacecraft body axis towards Boulder -- new integrated scenario in :ref:`scenarioAttitudeConstraintViolation`. Shows how to use the :ref:`boreAngCalc` to - display keep-in and keep-out constraint violations while performing slew maneuvers. -- updated :ref:`inertial3DSpin` to make the attitude input message optional, updated documentation to be RST only - and more descriptive of the associated math, and changed the module variable ``omega_spin`` to ``omega_RR0_R0`` -- enables the message ``recorder()`` module to function if the message structure contains structures itself. -- make the build system compatible with Python 3.8 and higher on Windows -- fixed custom RW support method in ``simIncludeRW.py`` -- fixed new C++20 related compiler warnings - -Version 2.0.2 -------------- -- new waypoint reference module in :ref:`waypointReference`. It can be used to read an attitude maneuver from a set of waypoints on a text file, likely generated outside Xmera. -- updated :ref:`gravityEffector` to allow the planet message module (``spiceInterface`` or ``planetEphemeris``) to - be called either before or after the ``spacecraft`` module update is called -- Fix a range of long-standing HTML Documentation build warnings and issues -- Renamed the messages ``CirclesOpNavMsgPayload`` to ``OpNavCirclesMsgPayload`` and - ``OpNavLimbMsgPayload`` to ``OpNavLimbMsgPayload`` to avoid sphinx naming conflicts -- unified the identical ``ukfUtilities.c/h`` files in ``attDetermination`` and ``opticalNavigation`` folders - into ``architecture/utilities`` -- added a new RW encoder simulation module :ref:`encoder` -- Fixed a bug in the onboardDataHandling module that allowed for data that did not exist to be downlinked -- changed default behavior of ``python3 conanfile.py`` to automatically compile the Xmera project. This was - a common stumbling point for new users. The build flag ``--buildProject`` can be used to enable automatic - compiling or not. For developers making new code this should likely be set to ``False`` when configuring - the project. -- Fixed a bug in :ref:`SimulationBaseClass` that prevented creating an event with multiple conditions -- added ``ShowExecutionOrder()`` method to :ref:`SimulationBaseClass` to print to the terminal the order that the - process, tasks and modules are executed. -- added ``ShowExecutionFigure()`` method to :ref:`SimulationBaseClass` to create a figure illustration the - execution order. -- added a new :ref:`xmeraPrinciples-2b` web page on how to visualize the BSK process, task and module execution -- added new ``bskSim`` example scenario showing how to alternate between flight modes in :ref:`scenario_AttModes` -- provide scripting support for Vizard 1.8.2 release - - -Version 2.0.1 -------------- -- Added the ability to clear the data of a message recorder using ``.clear()`` -- Fixed a rare issue where RW data didn't stick -- Fixed an issue subscribing to a C++ wrapped message object from python -- Cleaned up documentation on using datashaders and bokeh to interactively plot large simulation data sets. - The script :ref:`scenarioAnalyzeMonteCarlo` is updated to discuss the particular challenges in running this - datashader example of plotting data. -- enable Monte Carlo ``pytest`` test scripts to run on macOS if Python 3.9 or higher is used -- enable opNav scenario ``pytest`` test scripts to be tested by ``pytest`` if the build flag ``--opNav`` - is set to true and the path to :ref:`Vizard ` application is set in :ref:`BSK_OpNav`. -- fixed an issue that prevented subscribing to a C++ msg from python -- moved cModuleTemplate and :ref:`cppModuleTemplate` to a common folder ``src/moduleTemplates``. The - associated HTML documentation now appears inside the ``Documentation`` tab under ``moduleTemplates``. -- added the ``src/utilities/makeDraftModule.py`` script that is able to create a draft module template given - - - module name - - module description - - module location - - list of module input or output messages containing - - - message variable name - - message payload definition - - message description - - message type (ie. ``C`` or ``C++``) - - The script then generates either a C or C++ module folder that contains the elemental ``*.c/cpp``, ``*.h``, ``*.i`` - code which compiles into a functioning prototype module. Also included are the module ``*.rst`` file which provides - the basic description and message table (including hyperlinks to message payload type and message description), - as well as a functioning python unit test that loads the module, connects zero'd input messages and sets up - output message recorders. The coder can then take this draft module code and modify to achieve the desired - functionality. The page :ref:`Folder_moduleTemplates` discusses how to use it and provides to 2 sample - auto-generated modules that get created inside ``src/moduleTemplates`` with ``python conanfile.py``. -- new thermal motor module in :ref:`motorThermal`. It it be used to simulate the temperature of a RW motor. - - -Version 2.0.0 -------------- -- New message system with strong type checking. You now get a much simpler method to create message objects, - how to connect them within python, create stand-alone messages in python, etc. If you engage with a message - of the wrong type you get immediate compiler warnings. -- New C++ based message recording system that is much faster than the older python based message logging -- New messaging recording now stores the message data separately from the time a message was recorded - and the time the message was written -- Removed the arbitrary distinction between ``FSW``, ``SIM`` and ``INT`` messages. All messages are now - available to all modules -- Both C and C++ based message interfaces are now auto-generated when running ``python3 conanfile.py`` command -- New ability to create zero'd message structures in the modules -- Seamless message subscribing in Python across all modules types (C, C++ or Python) -- New generic RW device type in :ref:`simIncludeRW` and updated the support library to work with BSK2 -- Updated :ref:`simIncludeGravBody` to work with BSK2. If needed the :ref:`spiceInterface` and - :ref:`EpochMsgPayload` message is created within the gravity factory class. -- Updated :ref:`simIncludeThruster` to work with BSK2 -- Updated :ref:`fswSetupRW` to work with BSK2 -- Updated :ref:`fswSetupThrusters` to work with BSK2 -- Update Xmera module documentation that shows all input and output message variables, their - type and explanation -- Cleaned up the Xmera `src` folder layout by moving all Xmera architecture support files - to `src/architecture`. This impacts some include statements -- Made the C/C++ ``#include`` statements all relative to `src` to make it easier to find the associated - files in the source code -- Updated message names to now all comply with the Xmera message naming convention. See - :ref:`migrating-module-to-bsk2` for a table of how some message names have changed -- Updated :ref:`vizSupport` to work with BSK2. It is now much easier to include RW, thruster and CSS devices. - Further, the simulation gravity bodies don't have to be explicitly provided to the - ``vizSupport.enableUnityVisualization()`` method. Rather, these are pulled from the spacecraft object - directly. -- :ref:`reactionWheelStateEffector` is updated where the list of RW configuration parameters are now linked - from python, not copied. As a result it is now possible to stop the simulation and change RW parameters on - the fly, emulating a failure with a physical change in the RW mechanics. -- changed the output message type of :ref:`magnetometer` to be compatible with :ref:`tamComm` -- Created several instructional pages in the Quick-Start documentation folder. The examples folder - has moved to the Quick-Start guide as well. The new quick start guide now discusses - - - how to write Xmera python simulation scripts - - how to write C++, C and Python modules - -- Added installation instructions to run Xmera on a computer with the Apple M1 processor -- added :ref:`spacecraftLocation` module to allow checking for satellite to satellite line-of-sight access -- made ``maximumRange`` an optional variable in :ref:`groundLocation` -- renamed ``spacecraftDynamics`` to :ref:`spacecraftSystem`, and renamed the associated ``spacecraft`` to ``spacecraftUnit()``. -- renamed ``spacecraftPlus()`` to be now simply :ref:`spacecraft` -- renamed the `spacecraftPlus` associated messages to :ref:`SCStatesMsgPayload` and :ref:`SCMassPropsMsgPayload` -- renamed ``fswModuleTemplate()`` to be cModuleTemplate. This makes this naming consistent with the new :ref:`cppModuleTemplate`. -- renamed `rwMotorVoltageInterface` to :ref:`motorVoltageInterface`. This motor model can be used for both RW and hinged panel devices. -- added support to creating custom gravity bodies to :ref:`simIncludeGravBody`. Including support to have custom gravity bodies shown in :ref:`Vizard ` as well. The example script :ref:`scenarioCustomGravBody` provides an illustration of this functionality. - - - - -**Version 1.8.10** - -- Added support and expanded installation instructions making use of virtual environments - -**Version 1.8.9** - -- Added support for ``Location`` scripting in Vizard 1.7.1 -- Added a new documentation page discussing how to launch Vizard from the command line - and what optional arguments are available - -**Version 1.8.8** - -- The protobuffer interface files are now automatically created from - ``src/utilities/vizProtobuffer/vizMessage.proto`` without having to manually run the - ``protoc`` command each time the protobuffer message definitions changed. -- centerRadiusCNN is now supported on all the platforms -- Support Terminal Progress bar while running a Xmera simulation -- Improved the build system to re-swig the module if the dependencies have changed. - This avoids having to do a clean build or manually deleting the swing python files from within ``dist3/Xmera``. -- All unit test cases are compatible with windows platform -- Added scripting support for Vizard 1.7.0 - -**Version 1.8.7** - -- Updated ``orbitalMotion`` python and C libraries to include the new methods ``hillFrame()``, ``hill2rv()`` and ``rv2hill()`` -- Updated :ref:`dualHingedRigidBodyStateEffector` to support an output message of the panel angular states, an output message of the panel inertial position and attitude states, as well as upgrading the module to support ``spacecraftDynamics``. -- Updated :ref:`vizInterface` to support scripting of new Vizard 1.6.1 features - -**Version 1.8.6** - -- Fixed an issue where some Sim-FSW interface messages could not be written to from the Python layer -- Fixed an issue that prevented the ``opNav`` build mode to compile the OpenCV related libraries - on macOS with Xcode 12 installed -- renamed ``RWArraytorqueIntMsg`` to ``arrayMotorTorqueIntMsg`` -- updated :ref:`hingedRigidBodyStateEffector` to - - - write the panel angle and angle rate output message - - write the panel inertial and position states as an output message - - updated document to make use of RST format and specify module input and output messages -- updated ``eigenSupport.h`` to add new methods ``eigenMRPd2Vector3d()`` and ``eigenC2MRP()`` -- updated ``spacecraftPlus`` to allow the attitude motion to be prescribed through - an optional input message of type ``attRefMsg``. -- fixed sign issue in :ref:`simpleSolarPanel` -- support Vizard 1.6.0 scripting - - - -**Version 1.8.5** - -- Provide support of Vizard 1.5.1 scripting -- Updated conan to 1.29.2 to address issues building with opNav and support xcode 12 -- Disable freetype for windows because of opencv build issues. - -**Version 1.8.4** - -- update the macOS dependency to use either ``conan~=1.24`` or ``conan>=1.28``. The later resolves the linking issues - that ``conan`` had on macOS. Other platforms can use ``conan>=1.24.0``. -- updated ``vizInterface`` to support the latest features of Vizard 1.5, including the ability to show - relative trajectories -- updated :ref:`scenarioFormationBasic` example script to show more general orbits and the use - of the scientific camera sensor scripting -- On Windows the new build system now builds :ref:`vizInterface` - - -**Version 1.8.3** - -- Removed old ``CMakeLists.txt`` files that are no longer needed -- Improved the build process for Linux such that ``vizInterface`` and ``opNav`` related modules are available - again in Xmera python scripts. Thus Linux users can use 1.8.x onwards and still use these enhanced features. - The similar issue on the Windows platorm is not resolved yet. -- Updated setup instructions to remind the user to delete ``.conan`` folder if upgrading from a BSK version - prior to 1.8.0 -- Added support for Vizard 1.4.1 that allows setting default and thruster group plume colors. The built-in - thruster pluming length can be now be custo scaled as well. -- Added a video gallery page to the Vizard documentation section - -**Version 1.8.2** - -- Updated :ref:`dataFileToViz` to include the ability to read thruster force values. The spacecraft can have - multiple thruster sets, and this works for multiple spacecraft as well. See :ref:`test_dataFileToViz` for an - example on how to set this up. -- Updated :ref:`dataFileToViz` to include support for reaction wheel data. -- Updated documentation and ``CMakeLists.txt`` to required 3.14 or higher -- Updated how ``openCV`` is included to avoid false Xcode warnings about the library not being installed -- Added :ref:`centerRadiusCNN` for doing CNN-based image processing as well as a pre-trained model - (read by the module) that allows to extract center and apparent diameter from Mars - images. Note that for now this module is only built - on macOS systems. As we are able to test on other platforms we will include it there too. -- Added :ref:`scenario_CNNAttOD` to illustrate the use of the CNN-based image processing -- Added support for Vizard v1.4.0 scripting - -**Version 1.8.1** - -- Added a new folder ``externalTools/fswAuto`` that contains external tools to migrate BSK simulations and modules to C-code -- Added a new :ref:`albedo` which can simulate the average or data driven albedo of a single planet. This works - also if multiple celestial bodies are setup. -- New :ref:`scenarioAlbedo` to illustrate the use of :ref:`albedo` -- Made the RST HTML document creation work on Windows as well (see :ref:`createHtmlDocumentation`) -- Fixed the conan issues where the IDE only saw the Debug path of the Eigen library, not the Release path. - This gets rid of false warnings in Xcode that ```` could not be found. -- updated the installer script to automatically set the ``conan`` repo information. This removes one more step - from the installation process. - -**Version 1.8.0** - -- updated :ref:`imuSensor` to initialize all class variables in the constructor -- fixed a data frame issue in :ref:`groundLocation` -- first iteration of the CMake refactor completed. The refactor updates the project CMakeList to - - 1) conform with more modern CMake practices, - 2) allow developers to include custom dependencies on the module level with Custom.cmake files, - 3) refactors existing SWIG interface files to generate significantly smaller _wrap.c(xx) files, - 4) generates single libraries for GeneralModuleFiles rather than re-including, re-wraping, and - recompiling those files at the module level. The latter two changes provide significant - improvements in build time. - -- The need for folder module ``__init__.py`` files has been removed. If local python support files should be - included in the swig'd module, they can be included in the module ``*.i`` file using something like - ``%pythoncode "parseSRPLookup.py"``. -- The support files in ``_GeneralModuleFiles`` are now compiled into a library with the parent folder name. Thus, - the ``src/simulation/dynamics/_GeneralModuleFiles`` support files yield a swig'd library ``dynamicsLib``. - Similarly, ``src/simulation/environment/_GeneralModuleFiles`` yields ``environmentLib``. -- Cleaned up small RST documentation issues -- Updated the install process to check automatically for required python packages. They are not available, - then the user is prompted to install for user, for the system or cancel. -- Updated the install process to allow a user selectable checking of all optional python packages - through ``allOptBsk`` flag -- fixed memory issue in the :ref:`camera` -- Updated the HTML documentation process to provide tools to clean out the auto-generated documentation, - as well as to open the HTML output from the command line - -**Version 1.7.5** - -- Added the ability to shift the HSV or BGR colors of :ref:`camera` -- Updated :ref:`vizInterface` to allow the user to set the Vizard direct communication protocol, host name and port - number. -- fixed an issues in :ref:`simIncludeGravBody` where the method ``unloadSpiceKernels`` had the order of the spice package name and the spice path reversed 😟 -- New :ref:`dataFileToViz` that reads in spacecraft simulation states from a text file and converts them into - BSK messages. For example, this allows :ref:`vizInterface` store the simulation data into a Vizard compatible manner. -- Updated :ref:`spiceInterface` to allow for optional overriding the IAU planet frame with custom values -- Updated :ref:`vizInterface` to allow setting ``show24hrClock`` and ``showDataRateDisplay`` flags for Vizard files - supported in Vizard v1.3.0 - -Version 1.7.4 - -- hot-fix of an issue compiling Xmera on Windows. A ``#define _USE_MATH_DEFINES`` was missing that - Windows expected, but Unix systems didn't need - -**Version 1.7.3** - -- updated :ref:`scenarioFormationMeanOEFeedback` and :ref:`scenarioFormationReconfig` to increase - the orbit altitude to not hit the Earth. Also, added code that can be enabled to record the - simulation parameters for Vizard. -- updated :ref:`vizInterface` to support the latest Vizard v1.2.0 features. You can script that the spacecraft - and/or celestial objects are shown as sprites if they become very small. This makes it easier to see where - satellites are in a constellation or formation, as well as where Earth is if orbiting about Mars -- automated how the release number is pulled from a single txt file now - - -**Version 1.7.2** - -- new spacecraft formation flying control :ref:`meanOEFeedback` that implements a mean orbit element feedback - control law -- new relative orbit control tutorial example :ref:`scenarioFormationMeanOEFeedback` that uses :ref:`meanOEFeedback` -- updated documentation of cModuleTemplate to show how to make much simpler lists of module messages - using the ``list-table`` RST command -- new spaceraft relative motion control :ref:`spacecraftReconfig` that implements an orbit element based - impulsive feedback control strategy. The control is implemented with a thruster model and an - attitude guidance message is used to point the spacecraft in the correct direction. -- new example scenario :ref:`scenarioFormationReconfig` illustrating the use of the new impulsive relative motion - control module - -**Version 1.7.1** - -- Added the ability to detect if a satellite is visible to a ground location in the new :ref:`groundLocation` -- Added support to script Vizard to specify spacecraft, planet and actuator labels -- Added :ref:`spaceToGroundTransmitter` which simulates transmitting data from space to an antenna at a ground location. -- Added a nice new integrated scenario :ref:`scenarioGroundDownlink` that shows how to use :ref:`groundLocation` and :ref:`spaceToGroundTransmitter` -- Updated the definition of the variable noiseMatrix in ``gaussMarkov.h``, and PMatrix in ``simple_nav.h``, - ``imu_sensor.h`` and ``star_tracker.h`` - -**Version 1.7.0** - -- Fixed a transformation issue in ``eigenSupport.cpp`` where ``cArray2EigenMatrix3d()`` has to deal with - both column and row dominant matrix formulations. This only got used in :ref:`scenarioCSS` and the issue was offset - by an issue in ``setUnitDirectionVectorWithPerturbation()`` that compensated. Now, all is as it should be. -- Removed unneeded instances of using ``unitTestSupport.np2EigenVectorXd()`` when setting the spacecraft states -- Many new Xmera scenarios illustration interfacing with :ref:`Vizard ` to simulate opNav cases: - - - scenario_DoubleOpNavOD uses the two OpNav methods at once - - :ref:`scenario_faultDetOpNav` implements two OpNav methods and employs a fault detection - - :ref:`scenario_OpNavAttOD` uses the OpNav FSW stack to perform both pointing towards the target planet - - :ref:`scenario_OpNavAttODLimb` uses a Canny transform to extract limb points - - :ref:`scenario_OpNavHeading` point the spacecraft visually towards a target - - :ref:`scenario_OpNavOD` only performs the orbit determination component - - :ref:`scenario_OpNavODLimb` only performs the orbit determination component using the Limb based method - - :ref:`scenario_OpNavPoint` only performs the pointing component - - :ref:`scenario_OpNavPointLimb` only performs the pointing component using the Limb based method - - :ref:`scenario_LimbAttOD` performs a longer simulation using the limb based method - - :ref:`scenario_OpNavAttOD` performs a longer simulation using the Hough transform method - -- make :ref:`scenarioVizPoint` work with the latest :ref:`Vizard ` scripting methods - - - Add scripting support for the `customGUIScale` parameter - - All instrument cameras are now specified through `fieldOfView`, not sensor size and focal length - - Added scripting support to turn on camera boresight line or HUD frustum - - Made instrument cameras not render images to the home folder by default by setting `renderRate` to zero by default - - - -**Version 1.6.0** - -- Fixed the long-standing issue of not being able to run ``pytest`` on Windows from ``src``, but it only ran from - within sub-folders of ``src``. Still recommended to run on Windows multi-threaded ``pytest -n XXX`` - using ``pytest-xdist``. -- temporary fix for opencv not finding conan gflags for opencv sfm lib on windows. See the discussion - at ``_ -- Updated cModuleTemplate to include a message I/O figure and move it's message definition to ``simMessages`` -- Updated the documentation of :ref:`Folder_mrpPD` to the RST format -- Updated the documentation of :ref:`Folder_mrpSteering` to the RST format -- At long last, 🍾, created :ref:`GravityGradientEffector` which can simulate the gravity gradient torque acting on a - spacecraft due to the gravitational influence from one or more planets. -- Create a new example script :ref:`scenarioAttitudeGG` that illustrates the use of the gravity gradient effector -- Enhanced the ``GravBodyData`` class to now register the planet position, velocity, orientation and attitude - rate states. This allows other effectors, such as the gravity gradient effector, to have access to the current - planet states at any time step. -- added :ref:`ReactionWheelPower` which can compute the electrical power consumed by a reaction wheel device -- added new example script :ref:`scenarioAttitudeFeedbackRWPower` that illustrates doing a RW-based attitude - maneuver and tracking the RW power and net battery capacity left. -- added ``BCT_RWP015`` RW model template to the ``simIncludeRW.py`` support file - - -**Version 1.5.1** - -- Fixed an issue running :ref:`test_reactionWheelStateEffector_integrated` using Python 2 -- fixed a ``cmake`` issue where the module renaming from ``viz_interface`` to ``vizInterface`` was applied - -**Version 1.5.0** - -- Updated documentation for :ref:`eclipse` module with new RST format -- Updated cModuleTemplate documentation to show how to add equation numbers, cite equations, do bold math variables and cite a figure caption. -- Updated :ref:`reactionWheelStateEffector` and :ref:`vscmgStateEffector` such that max speed and max torque are consistently initialized to -1. A negative value was supposed to turn of speed and torque saturation, but this wasn't consistenly applied. -- Updated :ref:`reactionWheelStateEffector` such that the RW state output message was not hard-coded and un-changeable. Otherwise a BSK process could never have multiple spacecraft being simulated. Now, the rw effector ``modelTag`` is added to the beginning of the output message. This auto-generate method of message output names is avoided if the user sets the vector of output names from Python during the simulation setup. **Note:** Any prior BSK script that was logging the old auto-generated RW state messages will need to update the msg name now to work again. See :ref:`xmera-known-issues` for more information. -- Major enhancement to :ref:`vizInterface` where now multiple spacecraft can be added. You can create a list of spacecraft where :ref:`vizInterface` relies on common naming rules to find the right messages, or specify the messages for each spacecraft directly. This is demonstrated in :ref:`scenarioFormationBasic`. For now multiple craft with RW actuators are supported. Multi craft with thrusters will need to be added later. -- New spacecraft formation flying scenario :ref:`scenarioFormationBasic` where 3 satellites are flying 10m apart in a lead-follower configuration. Each has a different number of RWs. This scenario is a nice script to demonstrate the new multi-spacecraft support in Vizard. - -**Version 1.4.2** - -- added link to Xmera facebook page to Sphinx-based documentation -- made the html documentation compatible with dark mode on macOS, iOS and iPad OS browsers. If the user sets the system interface to dark mode, then the dark version of the web site is shown automatically. -- added a fix to cmake to get around a ``lipsodium`` and ``conan`` issue we are seeing on a Linux system - -**Version 1.4.1** - -- added :ref:`Vizard scripting ` abilities to control the new spacecraft camera view panel behaviors -- added :ref:`Vizard scripting ` abilities to specify custom CAD OBJ models to replace the default satellite shape -- added :ref:`Folder_onboardDataHandling` modules for simulating data generated, downlinked, and stored by instruments, transmitters, and storage units onboard a spacecraft. See :ref:`scenarioDataDemo` for a demo. -- updated :ref:`sunlineSuKF` with some general improvements -- tweak to ``cmake`` file to make BSK be portable across Linux systems -- changed the bskLogging level names to make them unique. This avoids potential variable name conflicts, especially on Windows. - -**Version 1.4.0** - -- updates to the Monte Carlo controller and plotting algorithms to make use of better use of Pandas and Datashader -- Added a message to the heading estimator in order to perform OpNav pointing -- added a general message to the Sphinx HTML documentation landing page -- updated the :ref:`bskModuleCheckoutList` with updated information and expectations -- Added a fault detection module for optical navigation -- Added camera module to own the message and to add corruptions to images -- Added a new support document :ref:`makingNewBskModule` on getting started writing BSK modules -- Added a new support document :ref:`addSphinxDoc` -- Updated the :ref:`aboutBSK` page to include Xmera highlights -- Made sure the Monte Carlo unit tests didn't leave any temporary data files behind -- Added new helper functions to the RW and Thruster factory classes to return the equivalent FSW configuration message. Updated :ref:`scenarioAttitudeFeedbackRW` simulation script to illustrate how to use such a helper function. -- Added a new Xmera logging system called bskLogging. This allows modules to print information with a variable verbosity level -- Include a new example scenario :ref:`scenarioBskLog` to illustrate how to use variable verbosity BSK notices - -**Version 1.3.2** - -- added the ability to include the unit test python files, along with their documentation, within the sphinx html documentation -- updated Vizard live streaming documentation -- updated unit test templates to have better formatting of the html validation report obtained with ``pytest --report`` -- exclude some un-needed files from the html documenation -- general sphinx documentation related fixed and enhancements - -**Version 1.3.1** - -- small fixes to the new HTML documentation -- correct the path includes in Monte Carlo Integrated tests -- updated the ``MRP_Steering`` module documentation to include plots of all test cases - -**Version 1.3.0** - -- Update template illustrating how the validation accuracy can be recording in the ``pytest`` parameters. -- Created a new method in ``SimulationBaseClass`` called ``pullMultiMessageLogData`` This is much faster in pulling the data log from multiple messages at once. -- It is no longer necessary to call sim.TotalSim.terminateSimulation() at the beginning of Xmera scripts. This call has been moved to the SimBaseClass constructor and removed from scripts in the repository. -- A new module in the environments directory, SolarFlux, provides the solar flux value at a spacecraft location including (optionally) eclipse effects -- New module in the navigation directory, PlanetHeading, provides the heading to a planet in the spacecraft body frame. There is a corresponding new message type BodyHeadingSimMsg. -- New Sphinx/Breathe based BSK documentation system! All documentation is still stored in the ``xmera/docs`` folder. The new system provides much better directory structure to access the BSK modules, and has a cleaner way to list the tutorial examples. - -**Version 1.2.1** - -- fixed an issued with the magnetometer module tests not passing on all platforms. The tolerances are now adjusted to pass everywhere. -- various improvements to the ``OpNav`` modules and ``vizInterface`` - -**Version 1.2.0** - -- Making the Python 3 compile flag be turned on by default. To compile with Python 2 the ``cmake`` flag ``-DUSE_PYTHON3`` can still be set to ``OFF`` -- Revised the FSW template module to use the updated in-line module documentation style which adds the description to the module ``*.h`` doxygen description, and adds the validation discussion as a doc-string to the ``test_xxx.py`` test file. -- make sure ``mrpRotation`` is non-singular for any general referene rotation. -- Created a Three-Axis-Magnetometer (TAM) sensor simulation model -- Created a TAM FSW communication model -- Changed the BSK ``ReadMessage()`` method to automatically zero the message memory space before reading in the data -- Added a base classes for battery energy storage and power consumption/provider nodes -- Added a simple power node module -- Added a simpler battery module -- Added a simple solar panel power module - - -**Version 1.1.0** - -- The circle finding module using openCV has been cleaned up and the noise is now dynamically measured given the image -- A new dispersion was added for Monte Carlo analysis which allows for per-axis control on an initial MRP value -- Cleaned up opNav messages to be consistent with other messages, and simplified the limbFinding code. Only functionality change is Gaussian Blur. -- Add new OpNav module using a planet limb. Algorithm developed by J. Christian -- Added support for OpenCV v 4.1.1 and Eigen library 3.3.7 -- fixed issue with Windows having trouble compiling due to use of ``uint`` -- added instructions on how to use the new Xcode 11 on macOS. This requires installing 2 more tools. Updated the install and macOS FAW pages. -- added the ability to ``pytest`` to use the ``--report`` flag to generate a comprehensive html test and validation document. All future modules should use this method to discuss the module validation. Legacy modules will be converted over time. -- Corrected an issue with some some BSK modules in a low memory computer environment - - - -**Version 1.0.0 🍾🍾🍾🍾🍾** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Added the ability to plot select BSK simulation data live as teh -simulation is running. See the new tutorials examples and the new FAQ -response page (under Support tab) on how to do this. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Lots of code clean up to remove compiler warnings about implicit -signedness conversions, print types, etc. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated ``scenarioMagneticFieldWMM.py`` scenario to store images into -the correct doxygen folder. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -[Bugfix] NRLMSISE-00 now defaults to kg/m^3 output, to be consistent -with other atmospheric density models. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added the ability to live stream the Xmera simulation data to Vizard! -This functions now in addition to saving BSK data to file and playing it -back later on. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.9.1** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Created a new attitude guidance module for OpNav: opNavPoint. Similar to -sunSafePoint, it matches a target heading with the OpNav heading for a -simple and robust solution. - -.. raw:: html - -
  • - -- added new tutorial on calling Python Spice functions within a Monte Carlo BSK simulation -- Added Keplerian Orbit utility class which is swig'd. This first implementation takes in elliptical orbit elements and can produce a range of related outputs like position, velocity, orbital period, etc. This makes it easier to create Keplerian orbits within python. -- Added a LimbFinding module for OpNav: limbFinding. This module performs a Canny transform to find the end of the planet and saves away the non-zero pixels for pose-estimation. -- made BSK compatible with both swig version 3 and 4 - -.. raw:: html - -
- -**Version 0.9.0** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Updated the MD help file on how to compile from the command line -environment using a custom configuration of Python. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Created new optical navigation filter that estimates bias in the -measurements. This filter takes in pixel and line data directly. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added the ability to specify Vizard settings from Xmera -``vizInterface`` module settings. This way Xmera simulations can set -the desired Vizard settings from within the simulation script. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added a new MD help file to discuss the helper methods that setup Vizard -features - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added a python helper function to setup cameraConfigMsg message and -create a custom camera view. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added the ability to script what starfield Vizard should use. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Made the Vizard helper check that correct keywords are being used. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The cmake file now turns ON by default the ``USE_PROTOBUFFERS`` and -``USE_ZMQ`` build flag options. This enables out of the box support for -saving BSK data to Vizard binary files. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.8.1** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Added a new kind of dispersion for Monte Carlos which disperses the -orbit with classic orbital elements instead of cartesian postion and -velocity. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added a new module that provides the Earth atmospheric neutral density -using the MSIS model. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated the Doxygen HTML documentation layout - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.8.0** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -ADDED PYTHON 3 SUPPORT! This is a major step for Xmera. Python 2 -remains suppored, but is now treated as a depreciated capability. It is -possible to compile BSK for P3 into a ``dist3`` folder, and for P2 into -a ``dist`` folder at the same time. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated the BSK installation notes to reflect a default installation -using Python 3 - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated all unit test BSK scripts to work in both Python 2 and 3 - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated all tutorial scripts to work in both Python 3 and 2. Default -instructions are now for Python 3 - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added a new support file with tips on migrating a Python 2 BSK script to -function in both Python 3 and 2. This is called Migrating BSK Scripts to -Python 3. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.7.2** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Added a new Earth magnetic field model based on the World Magnetic Model -(WMM). The module has PDF documetnation, and extensive unit test within -the source code folder, as well as a tutorial script demonstrating how -to run this. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated the ``spice_interface`` module to be able to read in an epoch -message - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated scenarios to use the epoch message - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Created a new support macro to convert a general date and time string -into an epoch message - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated the ``VizInterface`` module to now provide the reaction wheel -and thruster states to Vizard - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Cleaned up ``VizInterface`` to only subscribe to BSK messages that are -already created - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Adjust ``simpleNav`` to only subscribe to the sun message it is already -created - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Update all the tutorial scenario and bskSim simulations to use the -updated ``vizSupport.enableUnityVisualization`` method - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Fixed and cleaned up bugs in heading and opnav UKFs, pixelLineConverter, -houghCircles, and vizInterface - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added validity falg to OpNav messages in order to exclude potential -measurements - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Fixed camera orientation given the Unity camera frame definition - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated BSK installation instructions to warn about not using swig v4 - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.7.1** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Added a new plotting utility library to support interactive plotting -using datashaders with Python3. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Fixed a garbage collecting leak in the monte carlo controller to -minimize impact on computer memory. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.7.0** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Added the enableViz method to the bskSim scnearios. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added dvGuidance PDF module description - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added new orbital simulation tutorial on a transfer orbit from Earth to -Jupiter using a patched-conic Delta_v - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added the first image processing FSW module using OpenCV’s HoughCirlces. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added the a module to convert pixel/line and apparent diameter data from -circle-finding algorithm to a OpNav message with relative position and -covariance. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -New faceted model for atmospheric drag evaluation - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated RW and Thruster Simulation factory classes to use ordered -dictionary lists. This ensures that the devices are used in the order -they are added. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Fixed issue where the Viz would show a custom camera window on startup -if playing back a data file from bskSim scenarios. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added relative Orbit Determination filter (relativeODuKF) in -fswAlgorithms/opticalNavigation. This filter reads measurements treated -by the image processing block to estimate spacecraft position and -velocity - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Changed the C++ message ID to consitently be of type int64_t, not -uint64_t - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Rearchitected how data is retained in BSK monte carlo runs using Pandas. -The python pandas package is now required to run MC runs. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated the CMake to handle both Microsoft Visual Studio 2017 and 2019 - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added a new attitude control scenario that uses a cluster of thrusters -to produce the required ADCS control torque. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.6.2** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -hot fix that adds back a missing method in sim_model.c/h that causes the -``enableViz`` support method to not work. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated Viz_Interface module with opNavMode flag. This triggers logic to -link Xmera and Vizard with a TCP connection. This is ground work for -closed loop visual navigation capabilities. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated enableUnityViz python function in utilities/vizSupport. It now -takes in key word arguments to simplify the user interface. It also -reliably saves Vizard files for play back in the same directory as the -scenario that calls it. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.6.1** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Created a user guide MD file that is included in the BSK Doxygen HTML -documentation. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Removed the BOOST library from Xmera as it is no longer needed. This -makes the BSK repository much leaner. Note that this removes the -capability to communicate with the old Qt-based Visualization that is -now defunct and replaced with the new Vizard Visualization. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated switch unscented kalman filter for sunline estimation with code -cleanup and documentation updates. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated ``pytest`` environment to have markers registered - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -added a PPTX support file that explains the core Xmera architecture. -HTML documentation is updated to link to this. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Creates new simulation module called ``planetEphemeris`` which creates a -planet Spice ephemeris message given a set of classical orbit elements. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated the ``thrMomentumDumping`` module to read in the -``thrMomentumManagement`` module output message to determine if a new -momentum dumping sequence is required. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated the hillPoint and velocityPoint scenarios on how to connect a -planet ephemeris message. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated ``hillPoint`` and ``velocityPoint`` to meet BSK coding -guidelines - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated BSK_PRINT macro to automatically now add a new line symbol at -the end of the message - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.6.0** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Added a new ``vizInterface`` module. This version is able to record a -BSK simulation which can then be played back in the BSK Vizard -visualization program. Vizard must be downloaded separately. To enable -this capabilty, see the scenario tutorial files. -``scenariosBasicOrbit.py`` discusses how to enable this. The python -support macro ``vizSupport.enableUnityVisualization()`` is commented out -by default. Further, to compile ``vizInterface`` the CMake flags -``USE_PROTOBUFFERS`` and ``USE_ZEROMQ`` must be turned on. A new MD FAQ -support file discusses the Cmake options. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated ``inertialUKF`` module documentation and unit tests. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated unit test and documentation of ``dvAccumulation``. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -added a small include change to fix BSK compiling on Windows - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated unit test and documentation of ``sunlineEphem()`` - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated cmake files to set the policy for CMP0086 required by Cmake -3.14.x and higher - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated ``thrForceMapping`` module after code review with new expansive -unit tests and updated PDF documentation - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.5.1** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -updated the ``orbitalMotion.c/h`` support library to have more robust -``rv2elem()`` and ``elem2rv()`` functions. They now also handle -retrograde orbits. The manner in covering parabolic cases has changed -slightly. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -This module implements and tests a Switch Unscented Kalman Filter in -order to estimate the sunline direction. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added documentation to the ``dvAccumulation`` module and included proper -time info in the output message. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Providing new support functions to enable the upcoming Vizard Xmera -Visualization. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated the ‘oeStateEphem()’ module to fit radius at periapses instead -of SMA, and have the option to fit true versus mean anomaly angles. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated -’sunlineSuKF\ ``module which provides a switch Sunline UKF estimation filter. New documentation and unit tests.
  • updated 'MRP_Steering' module documentation and unit tests
  • updated orbital motion library functions``\ rv2elem()\ ``and elem2rv()`` - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated ``rateServoFullNonlinear`` module documentation and unit tests. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.5.0** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -``attTrackingError`` has updated documentation and unit tests. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -navAggregate module has new documentation and unit tests. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -small FSW algorithm enhancements to ensure we never divide by zero - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -new unit test for RW-config data - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -included a new environment abstract class that creates a common -interface to space environment modules like atmospheric density, or -magnetic fields in the future. This currently implements the exponential -model, but will include other models in the future. NOTE: this change -breaks earlier simulation that used atmospheric drag. The old -``exponentialAtmosphere`` model usage must be updated. See the -integrated and unit tests for details, as well as the module -documentation. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -added new documentation on using the new atmosphere module to simulate -the atmospheric density and temperature information for a series of -spacecraft locations about a planet. - -.. raw:: html - -
  • - -updated documentation and unit tests of ``celestialTwoBodyPoint`` - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -added a new planetary magnetic field module. Currently it provides -centered dipole models for Mercury, Earth, Jupiter, Saturn, Uranus and -Neptune. This will be expanded to provide convenient access to other -magnetic field models in the future. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated ``eulerRotation()`` to remove optional output message and did -general code clean-up - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated ``mrpRotation()``, new PDF documentation, did code cleanup, -updated unit tests, removed optional module output that is not needed - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated ``MRP_Feedback()``, new PDF documentation, did code cleanup, -updated unit tests to cover all code branches. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added a new tutorial on using the magnetic field model. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated ``mrpMotorTorque()`` with code cleanup, updated doxygen -comments, PDF documentation and comprehensive unit test. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added documentation to ``thrFiringRemainder`` module - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added documentation to ``thrFiringSchmitt`` module - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated documentation of ``thrMomentumManagement`` module - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated documentation of ``thrMomentumDumping`` module - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added documentation of ``MRP_PD`` module - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -added a new tutorial on how to use the planetary magnetic field model. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.4.1** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -cssComm has updated documentation and unit tests. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated Documentation on ``rwNullSpace`` FSW module - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated how the FSW and Simulation modules are displayed with the -DOxygen HTML documenation, as well as how the messages are shown. Now -the use can click on the “Modules” tab in the web page to find a cleaner -listing of all BSK modules, messages, utilities and architecture -documentation. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -modified the ``cmake`` file to allow the build type to be passed in from -the command line - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated Doxygen documentation on ``cssWlsEst()`` - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated documentation and unit tests of ``cssComm()`` module - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.4.0** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Integrated the ``conan`` package management system. This requires conan -to be installed and configured. See the updated Xmera installation -instructions. It is simple to add this to a current install. Further, -the CMake GUI application can’t be used directly with this -implementation if the app is double-clicked. Either the GUI is launched -form a terminal (see macOS installation instructions), or ``cmake`` is -run from the command line (again see your platform specific installation -instructions). Using ``conan`` now enables BSK to be compiled with -specific support packages, and will allow us to integrate other packages -like OpenCV, Protobuffers, etc. into the near future in a flexible -manner. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated install instructions to allow for pytest version 4.0.0 or newer - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated code to remove some depreciated python function call warnings - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added a new sun heading module computed exclusively from ephemeris data -and spacecraft attitude (sunlineEphem). Documentation and a unit test -are included. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added a new scenario that shows how to simulate multiple spacecraft in -one simulation instance. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added a spacecraftPointing module that allows a deputy spacecraft to -point at a chief spacecraft. Besides that, added a scenario that -demonstrates the use of this new module. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -added the ability to the thrForceMapping FSW module to handle thruster -saturation better by scaling the resulting force solution set. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added lots of new unit tests to BSK modules - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -rwNullSpace() module now sets ups module states in reset() instead of -crossInit(), and includes new documentation and unit tests - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.3.3** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Added a new message output with the CSS fit residuals. This is optional. -If the output message is not set, then this information is not computed. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated ``sunSafePoint()`` to allow for a nominal spin rate to be -commanded about the sun heading vector. The unit tests and module -documentation is updated accordingly. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added a new scenario ``scenarioAttitudeFeedbackNoEarth.py`` which -illustrates how to do an attitude only simulation without any gravity -bodies present. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated the macOS Xmera installation instructions to make them easier -to follow, and illustrate how to use the macOS provided Python along -with all the Python packages installed in the user Library directory. -This provides for a cleaner and easier to maintain Xmera -installation. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Created new switched CSS sun heading estimation algorithms called -``Sunline_SuKF`` and ``Sunline_SEKF``. These switch between two body -frames to avoid singularities, but with direct body rate estimation. -Previous filters ``Sunline_UKF``, ``Sunline_EKF``, and ``OKeefe_EKF`` -either subtract unobservability or difference sunheading estimate for a -rate approximation. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated the Windows specific install instructions to include explicit -steps for setting up and installing Xmera on machine with a fresh -copy of Windows 10. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added policy statements to the CMake files. This now silences the -warnings that were showing up in CMake 3.12 and 3.13 - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Modified CMake to silence the excessive warnings in XCode that -``register`` class is no depreciated in C++ - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.3.2** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Fixed an issue with the eclipse unit test. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -updated the installation instructions to warn about an incompatibility -between the latest version of ``pytest`` (version 3.7.1). Users should -use a version of ``pytest`` that is 3.6.1 or older for now until this -issue is resolved. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated the ``.gitignore`` file to exclude the ``.pytest_cache`` folder -that pytest generates with the newer versions of this program - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.3.1** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Tutorials added for BSK_Sim architecture. Added the ability to customize -the frequency for FSW and/or dynamics modules. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated the dynamics thruster factor classes. This streamlines how -thrusters can be added to the dynamics. Also, a new blank thruster -object is included in this factory class to allow the user to specify -all the desired values. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -bskSim now adds 8 thrusters to the spacecraft. These are not used yet, -but will be in future bskSim scenarios. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Modified how bskSim now includes CSS sensors in the spacecraft dynamics -setup - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Modified the FSW ``sunSafePoint()`` guidance module to read in the body -angular velocity information from standard ``NavAttIntMsg``. This will -break any earlier simulation that uses ``sunSafePoint()``. - -.. raw:: html - -
      - -.. raw:: html - -
    • - -FIX: update the ``sunSafePoint()`` input connection to use the current -message format. - -.. raw:: html - -
    • - -.. raw:: html - -
    - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Fixed an issue with energy not conserving if the fully coupled VSCMG -imbalance model is used. This imbalanced gimbal and wheel version now -conserves momentum and energy! - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added initial draft of VSCMG module documentation - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added documentation to all the bskSim scenarios inside -``src/test/bskSimScenarios``. The documentation now outlines how the -bskSim class can get setup and used to create complex spacecraft -behaviors with little code. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.3.0** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Updated cssWlsEst() module to also compute a partial angular velocity -vector. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -New FSW Guidance module ``mrpRotation()`` to perform a constant body -rate rotation. The initial attitude is specified through a MRP set. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Enhanced Linux installation instructions - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated the simIncludeThruster to use the same factor class as the RW -factory class. This will break old scripts that use the old method of -setting up Thrusters with this helper function. - -.. raw:: html - -
      - -.. raw:: html - -
    • - -FIX: Update the script to use the new factory class. Examples are seen -in -``src/simulation/dynamics/Thrusters/_UnitTest/test_thruster_integrated.py``. - -.. raw:: html - -
    • - -.. raw:: html - -
    - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated bskSim to use the RW factory class to setup the simulation RW -devices, as well as to use fsw helper functions to setup the RW FSW -config messages - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -At supportData/EphermerisData, updated the leap second kernel version to -from 0011 to 0012. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added a force and torque calculation method in the stateEffector -abstract class, and provided the necessary method calls in -``spacecraft``. This allows for stateEffectors to calculate the force -and torque that they are imparting on the rigid body hub. The -hingedRigidBodyStateEffector and the linearSpringMassDamper classes -provide their implementation of these calculations. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Fixed an issue with ``extForceTorque`` effector where the flag about -having a good input message was not being initialized properly. This -caused a rare failure in the unit test. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Reaction wheel state effector has an updated friction model that allows -the user to implement coulomb, viscous, and static friction. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Reaction wheel state effector now has max torque saturation logic in -which the wheels can only implement a maximum wheel torque and max wheel -speed saturation logic in which if the wheel speed goes over the maximum -wheel speed, then the wheel torque is set to zero. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -A new method called writeOutputStateMessages was added to the -stateEffector abstract class which allows for stateEffectors to write -their states as messages in the system and the states will always be -written out to the system after integration. This fixed an issue with -reaction wheels where the commanded torque information needs to be -tasked before the spacecraft but the reaction wheel state messages need -to be written out after integration. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -A new dynamics class called ``spacecraftDynamics`` has been created. -This allow multiple complex spacecraft systems to be either rigidly -connected or free-flying. This allow for example a mother craft to house -a daughter craft which has its own RWs, etc, and then release the -daughter craft at a specified time. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Cleaned up the gravity effector class variable names, and streamlined -the evaluation logic. The gravity effector documentation has been -updated to include information on the the multi-body gravity -acceleration is evaluated. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated the FSW modules ``MRP_Feedback``,\ ``MRP_Steering``, -``dvAccumulation`` and ``oeStateEphem`` to zero out the output message -first in the ``Update()`` routine. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Fixed an issue with the RW factory class and the Stribeck friction model -not being turned off by default. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -added a new bskSim based tutorial scenario that illustrates a -sun-pointing control while the spacecraft goes through a planets shadow. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.2.3 (June 12, 2018)** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Improved how the ``fuelSloshSpringMassDamper`` effector class works. It -is now renamed to ``LinearSpringMassDamper``. It can be used to simulate -both fuel sloshing, but also structural modes. If the -``LinearSpringMassDamper`` is connected to a fuel tank, then it’s mass -depends on the amount of fuel left. The associated unit test illustrated -how to setup this last capability. The module also contains -documentation on the associated math. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -A new ``SphericalPendulum`` effector class has been added. For rotations -a spherical pendulum is a better approximation rotational fuel slosh. -This effector can model rotational fuel slosh if connected to a tank -(see unit test again), or it can model a torsional structural mode if -not connected to a tank. Associated math documentation is included with -the class. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The booleans useTranslation and useRotation have been removed from the -``HubEffector()`` class. The defaults in hubEffector for mass -properties: ``mHub = 1``, ``IHubPntBc_B = diag``\ (1), and -``r_BcB_B = zeros(3)``, enable us to evaluate the same code no matter if -the desire is only to have translational states, only rotational states, -or both. This allows for less logic in hubEffector and removes -possibility of fringe cases that result in unexpected results from a -developer standpoint. The fix for if your python script is not working -related to this change: - -.. raw:: html - -
      - -.. raw:: html - -
    • - -FIX: Remove any instances of useTranslation or useRotation defined in -the hubEffector class. - -.. raw:: html - -
    • - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Changed name of the method ``computeBodyForceTorque`` to -``computeForceTorque`` in the ``dynamicEffector`` abstract class and any -inheriting classes. This avoids the confusion of thinking that only body -frame relative forces can be defined, but in reality this class gives -the ability to define both external forces defined in the body frame and -the inertial frame. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Fixed an issue in ``RadiationPressure`` where the cannonball model was -not computed in the proper frame. An integrated test has been added, and -the unit test is updated. Note that the ``RadiationPressure`` model -specification has changes slightly. The default model is still the -cannonball model. To specify another model, the python methods -``setUseCannonballModel()`` or ``setUseFacetedCPUModel()`` are used. -Note that these take no argument anymore. - -.. raw:: html - -
      - -.. raw:: html - -
    • - -FIX: remove the argument from ``setUseCannonballModel(true)`` and use -the methods ``setUseCannonballModel()`` or ``setUseFacetedCPUModel()`` -without any arguments instead. - -.. raw:: html - -
    • - -.. raw:: html - -
    - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.2.2 (May 14, 2018)** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Fixed a build issues on the Windows platform is Visual Studio 2017 or -later is used. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Unified the Coarse Sun Sensor (CSS) sun heading filtering modules to use -the same I/O messages. All used messages are now in the fswMessage -folder. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Made the CSS sun heading filter messages consistently use the CBias -value. This allows particular sensors to have an individual (known) -scaling correction factor. For example, if the return of one sensor is -10% stronger then that of the other sensors, then CBias is set to 1.10. -Default value is 1.0 assuming all CSS units have the same gain. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The ``src\tests\bskSimScenarios`` folder now functions properly with the -``bskSim`` spacecraft class. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The tutorial scripts in ``src\tests\scenarios`` are now simplified to -pull out the unit testing functionality. The unit testing is now down -with the ``test_XXX.py`` scripts inside the ``src\tests\testScripts`` -folder. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The ``bskSim`` tutorial files are now tested through pytest as well. The -file ``testScripts\bskTestScript.py`` calls all the ``bskSim`` tutorial -fails and ensures they run without error. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.2.1** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Added messages for current fuel tank mass, fuel tank mDot, and thruster -force and torque - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Changed the linearAlgebra.c/h support library to avoid using any dynamic -memory allocation. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added some new function to linearAlgebra.c/h while making the library -use the new BSK_PRINT() function. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added ability to simulate noise to the RW devices. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Created a more complete spacecraft python simulation class called -BSKsim, and recreated some BSK tutorial scripts to use BSKsim instead of -the more manual spacecraft setup in the earlier scripts. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Developed general functions to add saturation, discretization and Gauss -Markov processes to signals. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Created a new BSK_PRINT() function. Here the coder can tag a message as -an ERROR, WARNING, DEBUG or INFORMATION status. The printout can be set -to selectively show these print statements. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.2.0 (First public beta)** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -First open beta release of Xmera - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Moved to a new file architecture. This means older BSK python scripts -need to be updated as the method to import BSK has changed. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The source an now be forked from Bitbucket - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Precompiled binaries are provided through a python pip install wheel -file. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The Doxygen documentation now pulls in the BSK module description PDF -file and makes it available via the class definition html page. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The tutorial python scripts are now moved to ``src/test/scenarios`` - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The ``pytest`` common should now be run within the ``src`` sub-directory - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated fuel slosh model documentation - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated fuel tank documentation - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Adding noise and corruptions using a new utility to the BSK modules (in -progress) - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -New N-panel hinged rigid body module - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -New 2-panel hinged rigid body module - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added CSS sun-heading estimation tutorial script - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Added O’Keefe CSS sun-heading estimation module - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.1.7** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -New Monte-Carlo capability that uses multiple cores and hyperthreading -to accelerate the MC evaluations. Data is retained and stored for each -MC run for robustness. See ``test_scenarioMonteCarloAttRW.py`` for an -example. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Coarse Sun Sensor (CSS) modules can now scale the sensor output with the -distance from the sun. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -CSS now have updated documentation that includes validation results. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -CSS, IMU have updated means to apply sensor corruptions. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -IMU, simple_nav and star tracker modules have been updated to use now -internally Eigen vectors rather than C-Arrays. NOTE: if you have -simulation scripts that use these modules you may have to update the -script to set sensor states as Eigen vectors from python. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -All the dynamics, thruster and sensor simulation modules have expanded -documentation and valdiation unit and integrated tests. The validation -results are automatically included in the module TeX documentation. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.1.6** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -new unit tests to validate the multi-body gravity simulation code in -``SimCode/dynamics/gravityEffector/_UnitTest/test_gavityDynEffector.py`` - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -new hinged rigid body tutorial script in -``SimScenarios/test_scenarioAttGuideHyperbolic.py`` - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -new tutorial to do velicity frame pointing on a hyperbolic orbit in -``SimScenarios/test_scenarioHingedRigidBody.py`` - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -fixed various unit test issues that came up on the non-macOS builds - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -added reaction wheel effector documentation - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -added ``orb_elem_convert`` documentation - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -added ``boreAngCalc`` documentation - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.1.5** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -Lots of new module documentation which includes a discussion of what is -being modeled, the validation tests, as well as a user guide to the -module. The new documentation includes: - -.. raw:: html - -
      - -.. raw:: html - -
    • - -Thruster ``DynEffector`` module - -.. raw:: html - -
    • - -.. raw:: html - -
    • - -ephemeris conversion module - -.. raw:: html - -
    • - -.. raw:: html - -
    • - -Coarse Sun Sensor module - -.. raw:: html - -
    • - -.. raw:: html - -
    • - -Updated BSK module template documentation - -.. raw:: html - -
    • - -.. raw:: html - -
    • - -Updated documentation for IMU Sensor module - -.. raw:: html - -
    • - -.. raw:: html - -
    • - -Gravity Effector module - -.. raw:: html - -
    • - -.. raw:: html - -
    • - -SimpleNav Sensor module - -.. raw:: html - -
    • - -.. raw:: html - -
    • - -Hinged Panel ``StateEffector`` module - -.. raw:: html - -
    • - -.. raw:: html - -
    - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -New tutorial scripts on - -.. raw:: html - -
      - -.. raw:: html - -
    • - -using CSS modules - -.. raw:: html - -
    • - -.. raw:: html - -
    • - -using fuel tank module and the fuel slosh particle ``StateEffector`` - -.. raw:: html - -
    • - -.. raw:: html - -
    • - -How to use ``MRP_Steering()`` along with the rate tracking sub-servo -module - -.. raw:: html - -
    • - -.. raw:: html - -
    - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The CSS modules now use the planetary shadow message information to -simulated being in a planet’s shadow - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -SRP DynEffector modules now simulates the impact of being in a planets -shadow - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Included a method to validate all the AVS C-Function libraries like -``rigidBodyKinematics``, ``linearAlgebra`` and ``orbitalMotion`` when -the Xmera ``pytest`` command is called. There is also some -documentation on using these libraries in -``/SimCode/utilitiesSelfCheck/_Documentation`` - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated the RW and gravitational body (i.e. adding Earth, sun, etc. to -the simulation) to use new factory classes. If you did use the older -``simIncludeRW.py`` or ``simIncludeGravity.py`` libraries, you’ll need -to update your python code to work with the new factory classes. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.1.4** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -A planetary eclipse model has been added. This allows for the shadow of -one or multiple planets to be taken into account, including the penumbra -region. This module writes an output message indicating if the -spacecraft is in full sun light, partial shadow, or full shadow of the -sun. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The body-fixed spacecraft structure frame has now been removed from the -simulation and flight algorithm codes. All spacecraft vectors and -tensors are now set directly in the body frame B. If the spacecraft -parameters are given in terms of an alternate structure frame, these -vectors and tensor must be transformed into the body frame first before -being set in BSK. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The integrated tutorial test for using a Python based BSK module now has -some documentation. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Created a method to compute the orbital potential and angular momentum -energy. This allows for the kinetic energy and angular momentum checks -to flat-line even if the satellite is in orbit. The spherical harmonics -of the planet are taken into account as well. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Included a new Extended Kalman Filter module that determines the -body-relative sun heading using the CSS signals. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.1.3** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -There is a new capability to now write BSK modules in Python, and -integrated them directly with the C and C++ BSK modules. Documentation -is still in progress, but a sample is found in -SimScenarios/test_scenarioAttitudePythonPD.py. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -A new Variable Speed Control Moment Gyroscope (VSCMG) state effector -module has been created. This module provides a torque-level VSCMG -simulation which also includes the gyro frame or wheel being imbalanced. -If the latter modes are engaged, the simulation does slow down -noticeably, but you get the full physics. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -In the simulation the initial spacecraft position and velocity states -are now specified now using the spacecraft center of mass location C, -not the body fixed point B. This greatly simplifies the simulation -setup. Upon initialization, the sim determines what the true center of -mass of the spacecraft is using all time varying mass components, and -sets the proper B point position and velocity vectors. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Specifying the initial spacecraft position and velocity states can now -be done anywhere before the BSK initialization. The user sets init -versions of the position and velocity vectors. The setState() method on -the state engine thus doesn’t have to be used. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -There is a new initializeSimulationAndDiscover method to init the BSK -simulation that automatically checks if messages are shared across -multiple simulation threads. See the modified -SimScenarios/test_scenarioAttitudeFeedback2T.py file for how this -simplifies the dual-threaded setup. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The MRP_Steering and PRV_Steering FSW modules have been broken up into a -separate kinematic steering command (commanded desired angular velocity -vector) and an associated angular velocity servo module name -rateServoFullNonlinear. This will break any existing code that used -either of these two attitude steering modules. The Python simulation -code must be updated to to account for these new modules as done in the -MRP_Steering integrated test test_MRP_steeringInt.py. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.1.2** - - -.. raw:: html - -
    - -.. raw:: html - -
  • - -All unit and integrated tests now pass on Linux. The root issue was a -variable length string variable in an output message. These strings have -now been removed as they are no longer needed. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -The position and velocity of the center of mass of the spacecraft was -added to the messaging system, so now the spacecraft’s translational -states can be logged by the center of mass of the spacecraft (r_CN_N and -v_CN_N) or the origin of the body frame which is fixed to the hub -(r_BN_N and v_BN_N). Additionally, the mass properties of the spacecraft -was organized into an updateSCMassProps method that incapsulates the -calculations of mass property calculations. - -.. raw:: html - -
  • - -.. raw:: html - -
  • - -Updated UKF FSW module to be able to run on gryo only information when -the star tracker is not available. - -.. raw:: html - -
  • - -.. raw:: html - -
- -**Version 0.1.1** - -- On Linux, simplified the processing running BSK modules that require - boost. This makes the Viz related communication modules working again. -- Added boost libs built on Ubuntu against gcc 5.4.0 20160609. -- Added RPATH settings to allow for build directory to be placed outside - source directory -- Major addition with new depleatable mass dynamic modeling, including - some fuel tank dynamic models. -- minor fix for Monte Carlo dispersions - - -**Version 0.1.0** - - -**Simulation modules include:** - -.. raw:: html - -
    - -.. raw:: html - -
  • - - Flexible integration structure with fixed time step RK1, RK2 and RK4 - included
  • - -
  • Rigid spacecraft simulated through spacecraftPlus() module. The spacecraft object makes it simple to add external disturbances through dynEffectors and state depended actuation through stateEffectors. -
      -
    • Dynamics Effectors (actuation methods which do not have their own states to integrate)
    • -
        -
      • External force or torque module
      • -
      • Solar radiation pressure module
      • -
      • Thruster module
      • -
      -
    • State Effectors (actuation methods which have states to integrate)
    • -
        -
      • Fuel Tank model with fuel slosh particles
      • -
      • Hinged panel model to simulate flexing structures such as solar panels
      • -
      • Reaction wheel module with 3 modes (perfectly balanced, simple jitter with the disturbance modeled as an external force and torque, fully coupled imbalanced RW model) -
      -
    -
  • RW voltage interface module that mapes an input voltage to a RW motor torque
  • -
  • integrate Spice ephemeris information
  • -
  • simple navigation module that produces the position and attitude measurement states
  • -
  • IMU sensor
  • -
  • Star Tracker module
  • -
  • Coarse Sun Sensor (CSS) module
  • -
  • Added the ability to simulate the gravity from multiple celestial objects, as well as include spherical harmonic expansion of a particular celestial body.
  • - -.. raw:: html - -
- -**The AVS Lab Flight Algorithm folder contains:** - -- FSW template module -- CSS based sun heading estimation module -- UKF filter to determine inertial attitude -- UKF filter to determine CSS based body-relative sun heading -- Attitude Guidance modules: - - - Pointing towards two celestial objects - - Inertial Pointing - - Hill Frame Pointing - - Euler rotation sequence to add dynamics capabilities to the attitude reference generation - - Spinning about an inertially fixed axis - - A raster manager module that can change the guidance module states - - Velocity frame pointing - - attitude tracking error evaluation module - - Deadband module for attitude tracking error -- DV guidance module -- Effector Interfaces: - - - mapping of control torque onto RW motor torques - - Converting RW motor torques to voltages - - RW null motion module to equalize the wheel speeds continuously - - Thruster (THR) firing logic using a Schmitt trigger - - THR firing logic using a remainder calculation - - mapping of a command torque onto a set of THR devices - - module to evaluate the net momentum to dump with thrusters diff --git a/examples/BskSim/scenarios/scenario_AttGuidHyperbolic.py b/examples/BskSim/scenarios/scenario_AttGuidHyperbolic.py index 61133f2f3..e72ea229d 100644 --- a/examples/BskSim/scenarios/scenario_AttGuidHyperbolic.py +++ b/examples/BskSim/scenarios/scenario_AttGuidHyperbolic.py @@ -27,7 +27,7 @@ Custom Dynamics Configurations Instructions ------------------------------------------- -The modules required for this scenario are identical to those used in :ref:`scenario_AttGuidance`. +The modules required for this scenario are identical to those used in :ref:`BskSim_scenarios_scenario_AttGuidance`. Custom FSW Configurations Instructions -------------------------------------- diff --git a/examples/BskSim/scenarios/scenario_AttGuidance.py b/examples/BskSim/scenarios/scenario_AttGuidance.py index bc706e996..f90a243d0 100644 --- a/examples/BskSim/scenarios/scenario_AttGuidance.py +++ b/examples/BskSim/scenarios/scenario_AttGuidance.py @@ -25,20 +25,20 @@ .. image:: /_images/static/test_scenario_AttGuidance.svg :align: center -The initial setup for the simulation closely models that of :ref:`scenario_FeedbackRW`. +The initial setup for the simulation closely models that of :ref:`BskSim_scenarios_scenario_FeedbackRW`. Custom Dynamics Configurations Instructions ------------------------------------------- -The modules required for this scenario are identical to those used in :ref:`scenario_FeedbackRW`. +The modules required for this scenario are identical to those used in :ref:`BskSim_scenarios_scenario_FeedbackRW`. Custom FSW Configurations Instructions -------------------------------------- Three of the four modules required to configure the :ref:`hillPoint` FSW mode have already been included -within the :ref:`BSK_FSW` framework +within the :ref:`BskSim_models_BSK_Fsw` framework (``mrpFeedbackRWConfig()``, ``attTrackingErrorConfig()``, ``rwMotorTorqueConfig()``). The only remaining module is the hill pointing module itself which is set within ``__init__()``. diff --git a/examples/BskSim/scenarios/scenario_AttSteering.py b/examples/BskSim/scenarios/scenario_AttSteering.py index 6e84b5a2c..e2099052b 100644 --- a/examples/BskSim/scenarios/scenario_AttSteering.py +++ b/examples/BskSim/scenarios/scenario_AttSteering.py @@ -23,17 +23,17 @@ .. image:: /_images/static/test_scenario_AttSteering.svg :align: center -The initial conditions for the scenario are the same as found within :ref:`scenario_FeedbackRW`. +The initial conditions for the scenario are the same as found within :ref:`BskSim_scenarios_scenario_FeedbackRW`. Custom Dynamics Configurations Instructions ------------------------------------------- -The dynamics setup is the same as in :ref:`scenario_FeedbackRW`. +The dynamics setup is the same as in :ref:`BskSim_scenarios_scenario_FeedbackRW`. Custom FSW Configurations Instructions -------------------------------------- -To configure the desired "steeringRW" FSW mode the user must add the following modules to :ref:`BSK_FSW.py `. +To configure the desired "steeringRW" FSW mode the user must add the following modules to :ref:`BSK_FSW.py `. diff --git a/examples/BskSim/scenarios/scenario_BasicOrbit.py b/examples/BskSim/scenarios/scenario_BasicOrbit.py index bdca18d9b..5f06c7704 100644 --- a/examples/BskSim/scenarios/scenario_BasicOrbit.py +++ b/examples/BskSim/scenarios/scenario_BasicOrbit.py @@ -38,14 +38,14 @@ configurations and FSW modes neatly organized within three modular files: a ``BSK_scenario`` file, a FSW file, and a Dynamics file. -More explicitly, the purpose of the scenario file (in this case :ref:`scenario_BasicOrbit`) +More explicitly, the purpose of the scenario file (in this case :ref:`BskSim_scenarios_scenario_BasicOrbit`) within the ``BSK_Simulation`` architecture is to provide the user a simple, front-end interface to configure a scenario without having to individually initialize and integrate each dynamics and FSW module into their simulation. Instead the Dynamics file -(for instance :ref:`BSK_Dynamics` or :ref:`BSK_FormationDynamics`) +(for instance :ref:`BskSim_models_BSK_Dynamics` or :ref:`BskSim_models_BSK_FormationDynamics`) has preconfigured many dynamics modules, attached them to the spacecraft, and linked their messages to the appropriate FSW modules. -Similarly, the FSW file (in this case :ref:`BSK_FSW`) creates preconfigured FSW modes such as hill pointing, sun safe +Similarly, the FSW file (in this case :ref:`BskSim_models_BSK_Fsw`) creates preconfigured FSW modes such as hill pointing, sun safe pointing, velocity pointing, and more. Each preconfigured mode triggers a specific event which enables various FSW tasks like assigning enabling a specific pointing model or control loop. The proceeding sequence of tasks then initialize the appropriate FSW modules, link their messages, and provide pre-written FSW functionality through a simple @@ -65,7 +65,7 @@ tutorials) include sunSafePoint, inertial3D, velocityPoint, hillPoint, and more. Additionally, the user needs to supply initial conditions -for the spacecraft and its orbit. The example script code uses the :ref:`orbitalMotion` module to +for the spacecraft and its orbit. The example script code uses the ``orbitalMotion`` module to construct the appropriate position and velocity vectors for a stable orbit, and then assigns them to the spacecraft. @@ -84,7 +84,7 @@ reaction wheel pyramids, and coarse sun sensor constellations are all preconfigured; however, for users who would like to customize their own dynamics modules and FSW modes, it is recommended to copy the two primary ``BSK_Sim`` files -(:ref:`BSK_Dynamics.py ` and :ref:`BSK_FSW.py `) and modify them directly. +(:ref:`BSK_Dynamics.py ` and :ref:`BSK_FSW.py `) and modify them directly. Instructions for configuring user-customized Dynamics and FSW files are detailed below. @@ -92,13 +92,13 @@ Custom Dynamics Configurations Instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In :ref:`BSK_Dynamics`, the script first generates a dynamics task onto which +In :ref:`BskSim_models_BSK_Dynamics`, the script first generates a dynamics task onto which future dynamics modules will be added. Following the task generation, all desired dynamics module objects are generated: These objects are then configured through ``InitAllDynObjects(SimBase)`` which iterates through a number of setter functions that configure all of the dynamics objects properties and messages. These setter functions are examples of how the ``BSK_Sim`` architecture has preconfigured -dynamics modules within the :ref:`BSK_Dynamics`. +dynamics modules within the :ref:`BskSim_models_BSK_Dynamics`. Now, for every future scenario file, a spacecraft object, gravity effector, and simple navigation sensor will be available for use. Finally, all now-configured objects are attached to the DynamicsTask @@ -111,14 +111,14 @@ Custom FSW Configurations Instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:ref:`BSK_FSW.py `'s ``__init__()`` procedure defines all +:ref:`BSK_FSW.py `'s ``__init__()`` procedure defines all possible configuration messages to be used by future FSW algorithms. Because this scenario is simulating a 3-DOF spacecraft, there are no FSW algorithms needed to control attitude. -As such, a ``initializeStandby`` event is created within :ref:`BSK_FSW` to ensure all +As such, a ``initializeStandby`` event is created within :ref:`BskSim_models_BSK_Fsw` to ensure all FSW tasks are disabled. This event is -triggered by the modeRequest called in :ref:`scenario_BasicOrbit` and -executes the following code in :ref:`BSK_FSW`. +triggered by the modeRequest called in :ref:`BskSim_scenarios_scenario_BasicOrbit` and +executes the following code in :ref:`BskSim_models_BSK_Fsw`. Illustration of Simulation Results diff --git a/examples/BskSim/scenarios/scenario_BasicOrbitFormation.py b/examples/BskSim/scenarios/scenario_BasicOrbitFormation.py index 1ecaa6786..23dc3e773 100644 --- a/examples/BskSim/scenarios/scenario_BasicOrbitFormation.py +++ b/examples/BskSim/scenarios/scenario_BasicOrbitFormation.py @@ -11,16 +11,16 @@ #. highlight how the BSK_Sim structure of a formation flying tutorial is different from the basic orbit scenario, #. demonstrate how to create a formation flying scenario, and -#. how to customize the :ref:`BSK_FormationDynamics.py ` and :ref:`BSK_FormationFSW.py ` files. +#. how to customize the :ref:`BSK_FormationDynamics.py ` and :ref:`BSK_FormationFSW.py ` files. The script is found in the folder ``xmera/examples/BskSim/scenarios`` and executed by using:: python3 scenario_BasicOrbitFormation.py -The simulation mimics the basic simulation in the earlier tutorial in :ref:`scenario_BasicOrbit`. +The simulation mimics the basic simulation in the earlier tutorial in :ref:`BskSim_scenarios_scenario_BasicOrbit`. The flight software mode is set to inertial3D. The goal of this mode is to align the body axes of the spacecraft -with an inertial 3D point guidance coordinate system defined in :ref:`BSK_FormationFSW`. +with an inertial 3D point guidance coordinate system defined in :ref:`BskSim_models_BSK_FormationFsw`. However the flight software mode can also be set to "standby". The simulation layout is shown in the following illustrations. @@ -34,13 +34,13 @@ Configuring the scenario file ----------------------------- -The simulation layout is very similar to the one used for the :ref:`scenario_BasicOrbit` file. +The simulation layout is very similar to the one used for the :ref:`BskSim_scenarios_scenario_BasicOrbit` file. Two simulation processes are created: one which contains dynamics modules, and one that contains the Flight Software (FSW) modules. First of all, it can be observed that the Dynamics- and FSW files used are -the :ref:`BSK_FormationDynamics` and :ref:`BSK_FormationFSW` files. +the :ref:`BskSim_models_BSK_FormationDynamics` and :ref:`BskSim_models_BSK_FormationFsw` files. These two files have been created for this specific formation flying implementation into Xmera. -After initializing the interfaces and making sure that the :ref:`scenario_BasicOrbitFormation` +After initializing the interfaces and making sure that the :ref:`BskSim_scenarios_scenario_BasicOrbitFormation` class inherits from the BSKSim class, it is time to configure the initial conditions using the ``configure_initial_conditions`` method. It can be observed that two sets of @@ -49,7 +49,7 @@ class inherits from the BSKSim class, After that the function that logs the outputs can be observed. Again this looks very similar to the log_outputs method -in the :ref:`scenario_BasicOrbit` file, however one discrepancy can be noticed. Looking at +in the :ref:`BskSim_scenarios_scenario_BasicOrbit` file, however one discrepancy can be noticed. Looking at the code below it can be observed that two instances of the ``simpleNavObject`` are logged (``simpleNavObject`` and ``simpleNavObject2`` respectively). Each object corresponds @@ -63,7 +63,7 @@ class inherits from the BSKSim class, BSK_FormationDynamics file description -------------------------------------- -Looking at the :ref:`BSK_FormationDynamics` file, it can be observed that the dynamics +Looking at the :ref:`BskSim_models_BSK_FormationDynamics` file, it can be observed that the dynamics process consists of two tasks named DynamicsTask and ``DynamicsTask2`` respectively. These tasks are added to the dynamics process and to each task, an instance of a specific object is added. @@ -75,18 +75,18 @@ class inherits from the BSKSim class, After that each object is added to the corresponding task. Something that is very important is the message names. In case multiple spacecraft are implemented in Xmera it is necessary to manually connect an output message of one module to the input of a different module. This can be seen in the module-initialization methods -in the :ref:`BSK_FormationDynamics.py ` file. +in the :ref:`BSK_FormationDynamics.py ` file. BSK_FormationFsw file description --------------------------------- -The setup of the FSW file (:ref:`BSK_FormationFSW.py `) in case of +The setup of the FSW file (:ref:`BSK_FormationFSW.py `) in case of formation flying is very similar to the setup of the dynamics file. Also in this case, an instance of each task is initialized that corresponds to one of the two spacecraft. Furthermore, it is necessary to manually set the input- and output message names for the FSW modules. In order to make this tutorial work properly its is very important to set the ``self.mrpFeedbackRWs.Ki`` and ``self.mrpFeedbackRWs2.Ki`` -variables in :ref:`BSK_FormationFsw` to -1. Otherwise +variables in :ref:`BskSim_models_BSK_FormationFsw` to -1. Otherwise the orientation and rates of both spacecraft will not converge! diff --git a/examples/BskSim/scenarios/scenario_ClosedLoopManeuver.py b/examples/BskSim/scenarios/scenario_ClosedLoopManeuver.py index 1a87032ae..dc677ec83 100644 --- a/examples/BskSim/scenarios/scenario_ClosedLoopManeuver.py +++ b/examples/BskSim/scenarios/scenario_ClosedLoopManeuver.py @@ -23,22 +23,22 @@ Custom Dynamics Configurations Instructions ------------------------------------------- -Delta-V thrusters were added to the :ref:`BSK_Dynamics` framework. The properties of the DV thrusters can be changed -there, but keep in mind to also change the thruster properties in :ref:`BSK_FSW`. +Delta-V thrusters were added to the :ref:`BskSim_models_BSK_Dynamics` framework. The properties of the DV thrusters can be changed +there, but keep in mind to also change the thruster properties in :ref:`BskSim_models_BSK_Fsw`. Custom FSW Configurations Instructions -------------------------------------- -Delta-V thrusters were added to the :ref:`BSK_FSW` framework. The properties of the DV thrusters can be changed -there, but keep in mind to also change the thruster properties in :ref:`BSK_Dynamics`. Make sure to call +Delta-V thrusters were added to the :ref:`BskSim_models_BSK_Fsw` framework. The properties of the DV thrusters can be changed +there, but keep in mind to also change the thruster properties in :ref:`BskSim_models_BSK_Dynamics`. Make sure to call `FswModel.SetAttThrusters(useDvThrusters = True)` if it is desired to use the DV thrusters for attitude control, otherwise the ACS thrusters will be used by default. The necessary modules for attitude control with thrusters, i.e. :ref:`thrForceMapping` and :ref:`thrFiringRemainder` were added, and the module properties can be changed there. An additional MRP feedback module was added for thrusters. Modules for the DV execution, i.e. :ref:`dvGuidance` for DV attitude control and :ref:`dvExecuteGuidance` for maneuver -execution were also added and can be adjusted in :ref:`BSK_FSW`. +execution were also added and can be adjusted in :ref:`BskSim_models_BSK_Fsw`. Illustration of Simulation Results ---------------------------------- diff --git a/examples/BskSim/scenarios/scenario_FeedbackRW.py b/examples/BskSim/scenarios/scenario_FeedbackRW.py index fe61f133a..78ec56ab5 100644 --- a/examples/BskSim/scenarios/scenario_FeedbackRW.py +++ b/examples/BskSim/scenarios/scenario_FeedbackRW.py @@ -14,8 +14,8 @@ This script sets up a 6-DOF spacecraft orbiting Earth. The goal of the scenario is to -#. add reaction wheels to :ref:`BSK_Dynamics`, and -#. establish a inertial pointing FSW mode in :ref:`BSK_FSW`. +#. add reaction wheels to :ref:`BskSim_models_BSK_Dynamics`, and +#. establish a inertial pointing FSW mode in :ref:`BskSim_models_BSK_Fsw`. The script is found in the folder ``xmera/examples/BskSim/scenarios`` and executed by using:: @@ -31,15 +31,15 @@ Two simulation processes are created: one which contains dynamics modules, and one that contains the FSW -modules. The initial setup for the simulation closely models that of :ref:`scenario_BasicOrbit`. +modules. The initial setup for the simulation closely models that of :ref:`BskSim_scenarios_scenario_BasicOrbit`. Custom Dynamics Configurations Instructions ------------------------------------------- -In addition to the modules used in :ref:`scenario_BasicOrbit`, the user must configure the RW module -in :ref:`BSK_Dynamics` +In addition to the modules used in :ref:`BskSim_scenarios_scenario_BasicOrbit`, the user must configure the RW module +in :ref:`BskSim_models_BSK_Dynamics` to stabilize the tumbling. This is accomplished by first creating the RW state effector. The RW object is then configured through ``InitAllDynObjects(SimBase)`` which includes the ``SetReactionWheelDynEffector()`` @@ -50,14 +50,14 @@ -------------------------------------- To configure the desired :ref:`inertial3D` FSW mode the user must declare the following modules -within the ``__init__()`` function in :ref:`BSK_FSW`. +within the ``__init__()`` function in :ref:`BskSim_models_BSK_Fsw`. These provide the initial setup for an attitude guidance system that makes use of an inertial pointing model, a module that tracks the error of the spacecraft's MRP parameters against the pointing model, and a module that takes that information to provide a torque to correct for the error. -Following the initial declaration of these configuration modules, :ref:`BSK_FSW` +Following the initial declaration of these configuration modules, :ref:`BskSim_models_BSK_Fsw` calls a ``InitAllFSWObjects()`` command, -which, like :ref:`BSK_Dynamics`'s ``InitAllDynObjects()``, calls additional setter functions that configure each +which, like :ref:`BskSim_models_BSK_Dynamics`'s ``InitAllDynObjects()``, calls additional setter functions that configure each of the FSW modules with the appropriate information and message names. In addition to the modules used for attitude guidance, there are also two setter functions that send vehicle and RW @@ -76,7 +76,7 @@ the message this stand-alone message should be recorded. The output message payload within the module itself remain zero in such a case. -Finally, the :ref:`inertial3D` mode call in :ref:`scenario_FeedbackRW` needs to be triggered by:: +Finally, the :ref:`inertial3D` mode call in :ref:`BskSim_scenarios_scenario_FeedbackRW` needs to be triggered by:: SimBase.createNewEvent("initiateInertial3D", self.processTasksTimeStep, True, ["self.modeRequest == 'inertial3D'"], diff --git a/examples/BskSim/scenarios/scenario_LambertGuidance.py b/examples/BskSim/scenarios/scenario_LambertGuidance.py index 8be080c45..1243ae702 100644 --- a/examples/BskSim/scenarios/scenario_LambertGuidance.py +++ b/examples/BskSim/scenarios/scenario_LambertGuidance.py @@ -36,13 +36,13 @@ Custom Dynamics Configurations Instructions ------------------------------------------- -The modules required for this scenario are identical to those used in :ref:`scenario_BasicOrbit`. +The modules required for this scenario are identical to those used in :ref:`BskSim_scenarios_scenario_BasicOrbit`. Custom FSW Configurations Instructions -------------------------------------- -The five Lambert modules were added to the :ref:`BSK_FSW` framework. +The five Lambert modules were added to the :ref:`BskSim_models_BSK_Fsw` framework. The first maneuver event is triggered when a user calls `self.masterSim.modeRequest = 'lambertFirstDV'` in any current or future :ref:`Folder_BskSim` file, and the second maneuver using diff --git a/examples/BskSim/scenarios/scenario_RelativePointingFormation.py b/examples/BskSim/scenarios/scenario_RelativePointingFormation.py index 19ea27853..c99a1ffc6 100644 --- a/examples/BskSim/scenarios/scenario_RelativePointingFormation.py +++ b/examples/BskSim/scenarios/scenario_RelativePointingFormation.py @@ -17,7 +17,7 @@ python3 scenario_RelativePointingFormation.py The simulation mimics the basic simulation in the earlier tutorial in -:ref:`scenario_BasicOrbitFormation`. +:ref:`BskSim_scenarios_scenario_BasicOrbitFormation`. The flight software mode is set to spacecraftPointing. The goal of this mode is to align a vector given in the deputy's body-frame with a vector that points from the deputy to the chief spacecraft. @@ -36,13 +36,13 @@ Configuring the scenario file ----------------------------- -The simulation layout is almost the same as the one used for the :ref:`scenario_BasicOrbitFormation` file. +The simulation layout is almost the same as the one used for the :ref:`BskSim_scenarios_scenario_BasicOrbitFormation` file. Two simulation processes are created: one which contains dynamics modules, and one that contains the Flight Software (FSW) modules. First of all, it can be observed that the Dynamics- and FSW files used are -the :ref:`BSK_FormationDynamics` and :ref:`BSK_FormationFSW` files. +the :ref:`BskSim_models_BSK_FormationDynamics` and :ref:`BskSim_models_BSK_FormationFsw` files. These two files have been created for this specific formation flying implementation into Xmera. -After initializing the interfaces and making sure that the :ref:`scenario_BasicOrbitFormation` +After initializing the interfaces and making sure that the :ref:`BskSim_scenarios_scenario_BasicOrbitFormation` class inherits from the BSKSim class, it is time to configure the initial conditions using the ``configure_initial_conditions`` method. It can be observed that two sets of @@ -53,7 +53,7 @@ class inherits from the BSKSim class, conditions are set for each spacecraft. After that the function that logs the outputs can be observed. Again this looks very similar to the log_outputs function -in the :ref:`scenario_BasicOrbit` file, however one discrepancy can be noticed. Looking +in the :ref:`BskSim_scenarios_scenario_BasicOrbit` file, however one discrepancy can be noticed. Looking at the code below it can be observed that two instances of the simpleNavObject are logged (``simpleNavObject`` and ``simpleNavObject2`` respectively). Each object corresponds @@ -62,7 +62,7 @@ class inherits from the BSKSim class, BSK_FormationDynamics file description -------------------------------------- -Looking at the :ref:`BSK_FormationDynamics` file, it can be observed that the dynamics process consists of two tasks named ``DynamicsTask`` +Looking at the :ref:`BskSim_models_BSK_FormationDynamics` file, it can be observed that the dynamics process consists of two tasks named ``DynamicsTask`` and ``DynamicsTask2`` respectively. These tasks are added to the dynamics process and to each task, an instance of a specific object is added. @@ -72,12 +72,12 @@ class inherits from the BSKSim class, After that each object is added to the corresponding task. Something that is very important is the message names. In case multiple spacecraft are implemented in Xmera it is necessary to manually connect an output message of one module to the input of a different module. This can be seen in the module-initialization methods -in the :ref:`BSK_FormationDynamics.py ` file. +in the :ref:`BSK_FormationDynamics.py ` file. BSK_FormationFsw file description --------------------------------- -The setup of the FSW file (:ref:`BSK_FormationFSW`) in case of formation flying is +The setup of the FSW file (:ref:`BskSim_models_BSK_FormationFsw`) in case of formation flying is very similar to the setup of the dynamics file. Also in this case, an instance of each task is initialized that corresponds to one of the two spacecraft. Furthermore, it is diff --git a/examples/MultiSatBskSim/scenariosMultiSat/scenario_AttGuidMultiSat.py b/examples/MultiSatBskSim/scenariosMultiSat/scenario_AttGuidMultiSat.py index 2e871f2d9..e274ff129 100644 --- a/examples/MultiSatBskSim/scenariosMultiSat/scenario_AttGuidMultiSat.py +++ b/examples/MultiSatBskSim/scenariosMultiSat/scenario_AttGuidMultiSat.py @@ -17,8 +17,8 @@ python3 scenario_AttGuidMultiSat.py -This simulation is based on the :ref:`scenario_BasicOrbitMultiSat` with the addition of flight software modules. It also -takes some cues from :ref:`scenario_AttGuidance`, but with several spacecraft and more possible flight modes. +This simulation is based on the :ref:`MultiSatBskSim_scenariosMultiSat_scenario_BasicOrbitMultiSat` with the addition of flight software modules. It also +takes some cues from :ref:`BskSim_scenarios_scenario_AttGuidance`, but with several spacecraft and more possible flight modes. For simplicity, the script plots only the information related to one of the spacecraft, despite logging the necessary information for all spacecraft in the simulation. @@ -26,13 +26,13 @@ Custom Dynamics Configurations Instructions ------------------------------------------- -The dynamics modules required for this scenario are identical to those used in :ref:`scenario_BasicOrbitMultiSat`. +The dynamics modules required for this scenario are identical to those used in :ref:`MultiSatBskSim_scenariosMultiSat_scenario_BasicOrbitMultiSat`. Custom FSW Configurations Instructions -------------------------------------- -In this example, all spacecraft inherit the same flight software class defined in :ref:`BSK_MultiSatFsw`. Four flight +In this example, all spacecraft inherit the same flight software class defined in :ref:`MultiSatBskSim_modelsMultiSat_BSK_MultiSatFsw`. Four flight modes are implemented through the use of events and are described below: #. ``standby``: the spacecraft has no attitude requirements. @@ -40,17 +40,17 @@ #. ``sunPointing``: the spacecraft points at the Sun. #. ``locationPointing``: the spacecraft aims at a ground location on Earth. -The attitude is controlled using a set of four reaction wheels that are set up in :ref:`BSK_MultiSatDynamics`. The +The attitude is controlled using a set of four reaction wheels that are set up in :ref:`MultiSatBskSim_modelsMultiSat_BSK_MultiSatDynamics`. The ``mrpFeedback`` is used for the control law and ``rwMotorTorque`` interfaces with the reaction wheels. The ``attTrackingError`` module is used with all modes to convert from a reference message to a guidance one. The events can be set using the ``modeRequest`` flag inside the FSW class. It is crucial that all events call the ``setAllButCurrentEventActivity`` method. This function is called in a way such that all events' activity is made active except for the current one. Without this command, every event could only be made active once. The method also makes -sure it only affects the events specific to each spacecraft. For more information, see :ref:`SimulationBaseClass`. +sure it only affects the events specific to each spacecraft. For more information, see ``SimulationBaseClass``. No formation flying control is done in this scenario. To see a more complete example which includes formation geometry -control, see :ref:`scenario_StationKeepingMultiSat`. +control, see :ref:`MultiSatBskSim_scenariosMultiSat_scenario_StationKeepingMultiSat`. In this scenario, it is shown how the flight software events are set up, and how to change them on-the-fly. diff --git a/examples/MultiSatBskSim/scenariosMultiSat/scenario_BasicOrbitMultiSat.py b/examples/MultiSatBskSim/scenariosMultiSat/scenario_BasicOrbitMultiSat.py index 09678d2e8..ac28220e0 100644 --- a/examples/MultiSatBskSim/scenariosMultiSat/scenario_BasicOrbitMultiSat.py +++ b/examples/MultiSatBskSim/scenariosMultiSat/scenario_BasicOrbitMultiSat.py @@ -13,13 +13,17 @@ #. demonstrate how to create a formation flying scenario with any number of spacecraft, and #. show how to customize the environment, dynamics and flight software files. -The script is found in the folder ``xmera/examples/MultiSatBskSim/scenariosMultiSat`` and is executed by using:: +The script is found in the folder ``xmera/examples/MultiSatBskSim/scenariosMultiSat`` and is executed by using: + +.. code-block:: console python3 scenario_BasicOrbitMultiSat.py -The simulation mimics the basic simulation in the earlier tutorials in :ref:`scenario_BasicOrbit` and -:ref:`scenario_BasicOrbitFormation`. :ref:`scenario_BasicOrbit` introduces the use of the BSK_Sim structure and -its advantages, and :ref:`scenario_BasicOrbitFormation` simulates a basic scenario with two spacecraft using the BSK_Sim +.. highlight:: python + +The simulation mimics the basic simulation in the earlier tutorials in :ref:`BskSim_scenarios_scenario_BasicOrbit` and +:ref:`BskSim_scenarios_scenario_BasicOrbitFormation`. :ref:`BskSim_scenarios_scenario_BasicOrbit` introduces the use of the BSK_Sim structure and +its advantages, and :ref:`BskSim_scenarios_scenario_BasicOrbitFormation` simulates a basic scenario with two spacecraft using the BSK_Sim structure. However, this last scenario hard codes both spacecraft into the dynamics and flight software (FSW) classes. While this works for a small number of spacecraft, it is not easily scalable. This example aims to show a more pipelined way of adding spacecraft that can be either homogeneous or heterogeneous (different dynamics and flight software modules @@ -33,22 +37,22 @@ No flight software module is added in this scenario, only the environment and dynamics modules. However, for organization purposes the flight software module customization will also addressed. A more thorough review of the FSW -class can be read in :ref:`scenario_AttGuidMultiSat`. +class can be read in :ref:`MultiSatBskSim_scenariosMultiSat_scenario_AttGuidMultiSat`. Configuring the scenario file ----------------------------- -The simulation layout is very similar to the one used for the :ref:`scenario_BasicOrbitFormation` file. As stated +The simulation layout is very similar to the one used for the :ref:`BskSim_scenarios_scenario_BasicOrbitFormation` file. As stated before, several simulation processes are created: one for the environment and two for each of the spacecraft, each representing the dynamics and flight software modules. It is absolutely crucial that the environment model be created first, then the dynamics model for each spacecraft and then the FSW model for each spacecraft. In this case, the -Environment files used are :ref:`BSK_EnvironmentEarth` and :ref:`BSK_EnvironmentMercury`, whereas the Dynamics -file used is the :ref:`BSK_MultiSatDynamics`. The environment used in the simulation can be changed with either the +Environment files used are :ref:`MultiSatBskSim_modelsMultiSat_BSK_EnvironmentEarth` and :ref:`MultiSatBskSim_modelsMultiSat_BSK_EnvironmentMercury`, whereas the Dynamics +file used is the :ref:`MultiSatBskSim_modelsMultiSat_BSK_MultiSatDynamics`. The environment used in the simulation can be changed with either the ``Earth`` or ``Mercury`` flag on the ``run`` method. As stated before, the FSW file is not added in this scenario to focus first on setting up the dynamics of a number of spacecraft. All these files have been created for this specific formation flying implementation into Xmera but can be changed to accommodate any changes to the intended simulation. -After initializing the interfaces and making sure that the :ref:`scenario_BasicOrbitMultiSat` +After initializing the interfaces and making sure that the :ref:`MultiSatBskSim_scenariosMultiSat_scenario_BasicOrbitMultiSat` class inherits from the modified BSKSim class, the initial conditions are configured using the ``configure_initial_conditions`` method. This method cannot take advantage of the new BSK structure, and therefore the initial conditions for each spacecraft must be hard coded. Three sets of orbital elements are created, each @@ -56,7 +60,7 @@ class inherits from the modified BSKSim class, the initial conditions are config elements are converted to position and velocity and the initial conditions are set for each spacecraft. After that the function that logs the outputs can be observed. Again, this looks very similar to -the ``log_outputs`` method in the :ref:`scenario_BasicOrbitFormation` file. However, there is one difference: since multiple +the ``log_outputs`` method in the :ref:`BskSim_scenarios_scenario_BasicOrbitFormation` file. However, there is one difference: since multiple spacecraft are simulated, we must loop through each dynamics process and record each module. This makes the logging variables be lists of arrays instead of simply arrays. The same is true for the FSW objects. @@ -65,25 +69,25 @@ class inherits from the modified BSKSim class, the initial conditions are config BSK_EnvironmentEarth and BSK_EnvironmentMercury files description ----------------------------------------------------------------- -Both the :ref:`BSK_EnvironmentEarth` and :ref:`BSK_EnvironmentMercury` share the same structure, with a difference in the +Both the :ref:`MultiSatBskSim_modelsMultiSat_BSK_EnvironmentEarth` and :ref:`MultiSatBskSim_modelsMultiSat_BSK_EnvironmentMercury` share the same structure, with a difference in the gravity bodies used: the first uses the Sun, Earth and the Moon, while the second one only uses the Sun and Mercury. -The gravity bodies are created using :ref:`simIncludeGravBody` and their information is overridden by +The gravity bodies are created using ``simIncludeGravBody`` and their information is overridden by the SPICE library. An eclipse module is set up using the gravitational bodies used in the simulation. A ground location (representing Boulder's location on Earth) is also set to be used in flight software. All modules are added to the environment process. BSK_MultiSatDynamics file description ------------------------------------- -Looking at the :ref:`BSK_MultiSatDynamics` file, it can be observed that the dynamics process for each spacecraft +Looking at the :ref:`MultiSatBskSim_modelsMultiSat_BSK_MultiSatDynamics` file, it can be observed that the dynamics process for each spacecraft consists of one tasks named ``DynamicsTaskX`` where ``X`` represents that spacecraft's index. This task are added to the corresponding dynamics process and an instance of a specific object is added. The dynamics class creates a :ref:`spacecraft`, :ref:`simpleNav`, :ref:`reactionWheelStateEffector` and :ref:`thrusterDynamicEffector` objects. It also creates a :ref:`fuelTank` module that uses truster information to show the status of the onboard fuel tank. Although no attitude guidance and control is implemented in this example, this -class will be used in other scenarios that make use of those control surfaces (see :ref:`scenario_AttGuidMultiSat` and -:ref:`scenario_StationKeepingMultiSat`). +class will be used in other scenarios that make use of those control surfaces (see :ref:`MultiSatBskSim_scenariosMultiSat_scenario_AttGuidMultiSat` and +:ref:`MultiSatBskSim_scenariosMultiSat_scenario_StationKeepingMultiSat`). The dynamics script also sets up a number of power-related modules such as :ref:`simpleSolarPanel`, :ref:`simplePowerSink`, :ref:`simpleBattery` and :ref:`ReactionWheelPower`. diff --git a/examples/MultiSatBskSim/scenariosMultiSat/scenario_BasicOrbitMultiSat_MT.py b/examples/MultiSatBskSim/scenariosMultiSat/scenario_BasicOrbitMultiSat_MT.py index 60d6e3f88..5a60c6d84 100644 --- a/examples/MultiSatBskSim/scenariosMultiSat/scenario_BasicOrbitMultiSat_MT.py +++ b/examples/MultiSatBskSim/scenariosMultiSat/scenario_BasicOrbitMultiSat_MT.py @@ -9,10 +9,12 @@ This script demonstrates how to use the Xmera v2.1 multi-threading to simulate a constellation of 16 spacecraft using 4 threads. The simulation scenario setup is very similar to -:ref:`scenario_BasicOrbitMultiSat`. To setup the unique satellite orbits, the script here loops +:ref:`MultiSatBskSim_scenariosMultiSat_scenario_BasicOrbitMultiSat`. To setup the unique satellite orbits, the script here loops over all satellites an incrementally changes the orbit elements. The following Vizard screen capture illustrate the family of orbits being simulated. +.. highlight:: python + .. image:: /_images/static/scenario_BasicOrbitMultiSat_MT.jpg :align: center diff --git a/examples/MultiSatBskSim/scenariosMultiSat/scenario_StationKeepingMultiSat.py b/examples/MultiSatBskSim/scenariosMultiSat/scenario_StationKeepingMultiSat.py index 479975cc7..29a47a129 100644 --- a/examples/MultiSatBskSim/scenariosMultiSat/scenario_StationKeepingMultiSat.py +++ b/examples/MultiSatBskSim/scenariosMultiSat/scenario_StationKeepingMultiSat.py @@ -17,7 +17,7 @@ python3 scenario_StationKeepingMultiSat.py -This simulation is based on the :ref:`scenario_AttGuidMultiSat` with the addition of station keeping control. Attitude +This simulation is based on the :ref:`MultiSatBskSim_scenariosMultiSat_scenario_AttGuidMultiSat` with the addition of station keeping control. Attitude mode requests are processed in the same way as before, but now there is the added complexity of introducing formation control, which can influence attitude requests. @@ -33,18 +33,18 @@ Custom Dynamics Configurations Instructions ------------------------------------------- -The dynamics modules required for this scenario are the same used in :ref:`scenario_BasicOrbitMultiSat` and -:ref:`scenario_AttGuidMultiSat`. However, this example takes full advantage of all the features of the dynamics class, +The dynamics modules required for this scenario are the same used in :ref:`MultiSatBskSim_scenariosMultiSat_scenario_BasicOrbitMultiSat` and +:ref:`MultiSatBskSim_scenariosMultiSat_scenario_AttGuidMultiSat`. However, this example takes full advantage of all the features of the dynamics class, which includes thrusters for orbit corrections. Custom FSW Configurations Instructions -------------------------------------- -As stated in the previous section, the :ref:`BSK_MultiSatFsw` class used in this example is the same as the one used in -:ref:`scenario_AttGuidMultiSat`. The main difference is that the station keeping module is now used, which allows for +As stated in the previous section, the :ref:`MultiSatBskSim_modelsMultiSat_BSK_MultiSatFsw` class used in this example is the same as the one used in +:ref:`MultiSatBskSim_scenariosMultiSat_scenario_AttGuidMultiSat`. The main difference is that the station keeping module is now used, which allows for relative orbit geometry control. -If no station keeping is desired, then the FSW stack works exactly as in :ref:`scenario_AttGuidMultiSat`. However, if +If no station keeping is desired, then the FSW stack works exactly as in :ref:`MultiSatBskSim_scenariosMultiSat_scenario_AttGuidMultiSat`. However, if station keeping is set properly, the FSW events work as follows. First, the attitude reference is set given the pointing requirements. Then, the station keeping module computes the information regarding the necessary corrective burns, such as point in orbit, duration, thrust, attitude requirements, etc. With this information, the module then chooses whether @@ -66,7 +66,7 @@ Due to the fact that the ``spacecraftReconfig`` module only accepts messages of the type :ref:`attRefMsgPayload`, the ``locationPointing`` module always outputs a reference message and the ``attTrackingError`` module is always called, -unlike how it happens in :ref:`scenario_AttGuidMultiSat`. +unlike how it happens in :ref:`MultiSatBskSim_scenariosMultiSat_scenario_AttGuidMultiSat`. Illustration of Simulation Results ---------------------------------- diff --git a/examples/OpNavScenarios/BSK_OpNav.py b/examples/OpNavScenarios/BSK_OpNav.py index 690f97bad..ee166e13c 100644 --- a/examples/OpNavScenarios/BSK_OpNav.py +++ b/examples/OpNavScenarios/BSK_OpNav.py @@ -11,12 +11,14 @@ All of the scenarios provided in ``xmera/examples/OpNavScenarios`` put a spacecraft on orbit about Mars. By extracting limbs are circles from the images, the spacecraft can point to the planet, and estimate it's position. +.. highlight:: python + .. image:: /_images/static/OpNavScenario.png :align: center This Xmera Simulation, which inherits ``SimulationBaseClass``, provides the backbone for all the OpNav simulations provided in ``xmera/examples/OpNavScenarios``. -These simulations spawn the Xmera :ref:`Vizard ` visualization in order to provide images for processing. +These simulations spawn the Xmera ``Vizard`` visualization in order to provide images for processing. These images are handled by the vizInterface module found in ``src/simulation/vizInterface``. A figure illustrating the architecture is found here: @@ -51,7 +53,9 @@ Vizard connection). Another option is to manually open the Vizard application after having started the python scenario, check OpNav or Direct Comm, and provide the tcp/ip address printed by the scenario. -The scripts are tested if all modules are installed, but can be run at full length by calling:: +The scripts are tested if all modules are installed, but can be run at full length by calling: + +.. code-block:: console python3 scenario_OpNavAttOD.py @@ -72,14 +76,14 @@ The simulations use three other main python scripts. -:ref:`BSK_OpNavDynamics` is similar to the BSKSim versions seen previously. The main additions are +:ref:`OpNavScenarios_modelsOpNav_BSK_OpNavDynamics` is similar to the BSKSim versions seen previously. The main additions are the instantiation of :ref:`vizInterface`, and the camera module. -:ref:`BSK_OpNavFsw` contains the FSW algorithms used in the scenarios. Examples are the Orbit Determination +:ref:`OpNavScenarios_modelsOpNav_BSK_OpNavFsw` contains the FSW algorithms used in the scenarios. Examples are the Orbit Determination filters, the pointing guidance module, the CNN module, and more. This file also contains the ``modeRequest`` definitions which enable all the tasks necessary to perform a specific action. -:ref:`OpNav_Plotting` contains the plotting routines. None of the files are saved, but are shown when +:ref:`OpNavScenarios_plottingOpNav_OpNav_Plotting` contains the plotting routines. None of the files are saved, but are shown when the scenario is run with python. Saving is left to the user's discretion. """ diff --git a/examples/scenarioAerocapture.py b/examples/scenarioAerocapture.py index 59201479f..c42ae036b 100644 --- a/examples/scenarioAerocapture.py +++ b/examples/scenarioAerocapture.py @@ -7,11 +7,15 @@ Overview -------- +.. highlight:: python + Demonstrates a spacecraft performing aerocapture. :ref:`tabularAtmosphere` is used to read in a table of atmospheric density value for the planet. A cannonball drag effector (:ref:`dragDynamicEffector`) is used to simulate the atmospheric drag force. -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioAerocapture.py @@ -27,7 +31,7 @@ :: - show_plots = True, planetCase = `Earth` + show_plots = True, planetCase = 'Earth' .. image:: /_images/Scenarios/scenarioAerocapture5Earth.svg :align: center @@ -47,7 +51,7 @@ :: - show_plots = True, planetCase = `Mars` + show_plots = True, planetCase = 'Mars' .. image:: /_images/Scenarios/scenarioAerocapture5Mars.svg :align: center diff --git a/examples/scenarioAsteroidArrival.py b/examples/scenarioAsteroidArrival.py index b0c071206..06500c5ae 100755 --- a/examples/scenarioAsteroidArrival.py +++ b/examples/scenarioAsteroidArrival.py @@ -16,10 +16,14 @@ meters. The spacecraft then completes a series of Hohmann transfers while also conducting several attitude changes until reaching a final elliptical orbit about the asteroid. -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioAsteroidArrival.py +.. highlight:: python + .. attention:: To see the asteroid Bennu in Vizard the asteroid asset bundle must be installed. See diff --git a/examples/scenarioAttitudeConstraintViolation.py b/examples/scenarioAttitudeConstraintViolation.py index 6715f7f1b..72f4e7e34 100644 --- a/examples/scenarioAttitudeConstraintViolation.py +++ b/examples/scenarioAttitudeConstraintViolation.py @@ -30,7 +30,7 @@ from an initial to a final inertially fixed attitude, the reader is redirected to :ref:`scenarioAttitudeFeedbackRW` where this process is explained in the details. -This script uses :ref:`simIncludeGravBody` to add Earth and Sun to the simulation. The method ``createSpiceInterface`` +This script uses ``simIncludeGravBody`` to add Earth and Sun to the simulation. The method ``createSpiceInterface`` to create Spice modules for the celestial bodies and generate the respective Spice planet state messages. The :ref:`boreAngCalc` module is set up for each of the instruments that have geometric angular constraints. This module subscribes to the :ref:`SCStatesMsgPayload` and :ref:`SpicePlanetStateMsgPayload` of the bright object (the Sun) and diff --git a/examples/scenarioAttitudeFeedbackRW.py b/examples/scenarioAttitudeFeedbackRW.py index c92b21a62..78ff8168a 100755 --- a/examples/scenarioAttitudeFeedbackRW.py +++ b/examples/scenarioAttitudeFeedbackRW.py @@ -12,6 +12,8 @@ Overview -------- +.. highlight:: python + Demonstrates how to use RWs to stabilize the tumble of a spacecraft orbiting the Earth. This script sets up a 6-DOF spacecraft which is orbiting the Earth. The goal is to illustrate how the Reaction Wheel (RW) state effector can be added to the rigid :ref:`spacecraft` hub, @@ -21,7 +23,9 @@ which are then connected directly to the RW device input states. The second setup illustrates how to setup voltage based I/O modules to the RW devices, both on the FSW and SIM side. -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioAttitudeFeedbackRW.py @@ -58,7 +62,7 @@ The next step in this simulation setup is to use create() to include a particular RW devices. -The `rwFactory` class in :ref:`simIncludeRW` contains several +The `rwFactory` class in ``simIncludeRW`` contains several public specifications of RW devices which can be accessed by specifying the wheel name, ``Honeywell_HR16`` in this case. The 2nd required argument is the spin axis :math:`\hat{\mathbf g}_B`. It is a unit vector expressed in the :math:`\cal B`-frame. The remaining arguments are all optional. In this simulation diff --git a/examples/scenarioAttitudeFeedbackRWPower.py b/examples/scenarioAttitudeFeedbackRWPower.py index 6c92e7a24..02b5d7bdc 100755 --- a/examples/scenarioAttitudeFeedbackRWPower.py +++ b/examples/scenarioAttitudeFeedbackRWPower.py @@ -18,7 +18,7 @@ The simulation layout is shown in the following illustration. A single simulation process is created which contains both the spacecraft simulation modules, as well as the Flight Software (FSW) algorithm modules. The 3 separate :ref:`ReactionWheelPower` instances are created to model the RW power requirements. -For more examples on using the RW power module see :ref:`test_unitReactionWheelPower`. +For more examples on using the RW power module see ``test_unitReactionWheelPower``. Next, a battery module is created using :ref:`simpleBattery`. All the RW power draw messages are connected to the battery to model the total energy usage. diff --git a/examples/scenarioAttitudeGG.py b/examples/scenarioAttitudeGG.py index b0d58e9ff..668f50b21 100755 --- a/examples/scenarioAttitudeGG.py +++ b/examples/scenarioAttitudeGG.py @@ -10,7 +10,7 @@ Illustrates how to add a :ref:`GravityGradientEffector` to a 6U cube-sat spacecraft while a Hill-frame pointing control solution is active. This script expands on :ref:`scenarioAttitudeGuidance` sets up a 6-DOF spacecraft which is orbiting the Earth. More illustrations on using the gravity gradient -torque effector can be found in the modules :ref:`UnitTestGravityGradientEffector` folder. +torque effector can be found in the modules ``unitTestGravityGradientEffector`` folder. The script is found in the folder ``xmera/examples`` and executed by using:: diff --git a/examples/scenarioBasicOrbit.py b/examples/scenarioBasicOrbit.py index 88326a369..a91412387 100644 --- a/examples/scenarioBasicOrbit.py +++ b/examples/scenarioBasicOrbit.py @@ -12,6 +12,8 @@ Overview -------- +.. highlight:: python + This scenario demonstrates how to set up a spacecraft orbiting a celestial body. The gravity can be a first order approximation or run with high-order spherical harmonic terms. The following diagram illustrates how the Xmera components are interconnected. @@ -19,7 +21,9 @@ .. image:: /_images/static/test_scenarioBasicOrbit.svg :align: center -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioBasicOrbit.py diff --git a/examples/scenarioBasicOrbitStream.py b/examples/scenarioBasicOrbitStream.py index 8bd1987e4..d43b9e875 100644 --- a/examples/scenarioBasicOrbitStream.py +++ b/examples/scenarioBasicOrbitStream.py @@ -9,7 +9,7 @@ This script duplicates the basic orbit simulation in the scenario :ref:`scenarioBasicOrbit`. The difference is that this version allows for the Xmera simulation data to be live streamed to the -:ref:`vizard` visualization program. +``Vizard`` visualization program. The script is found in the folder ``xmera/examples`` and executed by using:: diff --git a/examples/scenarioCustomGravBody.py b/examples/scenarioCustomGravBody.py index 4556f0227..3ddededa3 100755 --- a/examples/scenarioCustomGravBody.py +++ b/examples/scenarioCustomGravBody.py @@ -20,7 +20,7 @@ :align: center Further, the Vizard binary file is setup to load up a custom CAD model for the asteroid. The spacecraft -orbit is defined relative to the asteroid. Note, this feature requires :ref:`Vizard ` version 1.8 or higher. +orbit is defined relative to the asteroid. Note, this feature requires ``Vizard`` version 1.8 or higher. The script is found in the folder ``xmera/examples`` and executed by using:: @@ -36,7 +36,7 @@ while Earth is on a circular orbit and Itokawa is on its elliptical heliocentric orbit. The method ``createCustomGravObject()`` is used to create the BSK grav bodies for both earth and Itokawa. -The earth body is already supported in :ref:`simIncludeGravBody`, but in this script we show how this could +The earth body is already supported in ``simIncludeGravBody``, but in this script we show how this could be customized. The gravity body ephemeris states are connected to the :ref:`planetEphemeris` planet state output messages. diff --git a/examples/scenarioDataToViz.py b/examples/scenarioDataToViz.py index 18a792127..1bb050342 100755 --- a/examples/scenarioDataToViz.py +++ b/examples/scenarioDataToViz.py @@ -8,7 +8,7 @@ -------- Demonstrates how to convert spacecraft states, stored in a text file from another program, into Xmera -messages using :ref:`dataFileToViz`. These messages are red by :ref:`vizInterface` to save a :ref:`Vizard ` +messages using :ref:`dataFileToViz`. These messages are red by :ref:`vizInterface` to save a ``Vizard`` compatible data play for offline playback and analysis. In this simulation a servicer is holding a relative position with respect to an uncontrolled satellite. Custom spacecraft models are specified for Vizard in the folder ``dataForExamples``. diff --git a/examples/scenarioDebrisReorbitET.py b/examples/scenarioDebrisReorbitET.py index b1e66d24f..ab6e35444 100644 --- a/examples/scenarioDebrisReorbitET.py +++ b/examples/scenarioDebrisReorbitET.py @@ -8,10 +8,10 @@ -------- Demonstrates a basic debris reorbit scenario from geostationary orbit using the Electrostatic Tractor (ET) concept and how to visualize the simulation -data in :ref:`Vizard `. This scenario shows how to use the :ref:`etSphericalControl` module for ET relative +data in ``Vizard``. This scenario shows how to use the :ref:`etSphericalControl` module for ET relative motion control and also illustrates the usage of the :ref:`msmForceTorque` to calculate the electrostatic forces with the Multi-Sphere Method (MSM). This simulation simply uses a single sphere to represent each spacecraft. The servicing satellite is charged to a positive electric potential, while the other satellite (the debris) is uncontrolled and charged to a negative potential. The purpose of this script is to show an explicit method to setup the ET reorbit simulation, and also show how to store the Xmera simulation data to be able to visualize -both satellite's motions within the :ref:`Vizard ` application. +both satellite's motions within the ``Vizard`` application. The script is found in the folder ``src/examples`` and executed by using:: diff --git a/examples/scenarioDragRendezvous.py b/examples/scenarioDragRendezvous.py index a5170b797..014b27f7a 100644 --- a/examples/scenarioDragRendezvous.py +++ b/examples/scenarioDragRendezvous.py @@ -7,10 +7,14 @@ Overview -------- +.. highlight:: python + This script sets up a formation flying scenario with two spacecraft. The deputy spacecraft attempts to rendezvous with the chief using attitude-driven differential drag using the strategy outlined in `this paper `_. -This script is found in the folder ``src/examples`` and executed by using:: +This script is found in the folder ``src/examples`` and executed by using: + +.. code-block:: console python3 scenarioDragRendezvous diff --git a/examples/scenarioFlybySpice.py b/examples/scenarioFlybySpice.py index 7e1e809a5..caa3d7dca 100644 --- a/examples/scenarioFlybySpice.py +++ b/examples/scenarioFlybySpice.py @@ -7,12 +7,16 @@ Overview -------- +.. highlight:: python + The purpose of this simulation is to illustrate how to set a spacecraft's translational motion using a custom Spice file for planetary flybys. This allows the user to easily visualize a mission trajectory using Vizard. Attitude pointing modes are also implemented in this script to enhance the mission simulation and illustrate other capabilities in Xmera. -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioFlybySpice.py diff --git a/examples/scenarioFormationBasic.py b/examples/scenarioFormationBasic.py index ec0c4c07b..4c182f698 100755 --- a/examples/scenarioFormationBasic.py +++ b/examples/scenarioFormationBasic.py @@ -8,11 +8,11 @@ -------- Demonstrates a basic method to simulate 3 satellites with 6-DOF motion and how to visualize the simulation -data in :ref:`Vizard `. One satellite is a 3-axis attitude controlled +data in ``Vizard``. One satellite is a 3-axis attitude controlled satellite, while the second satellite is a tumbling space debris object. The controlled satellite simulation components are taken from :ref:`scenarioAttitudeFeedbackRW`. The purpose of this script is to show an explicit method to setup multiple satellites, and also show how to store the Xmera simulation data to be able to visualize -both satellite's motions within the :ref:`Vizard ` application. +both satellite's motions within the ``Vizard`` application. Note, this scenario also illustrates how to ensure that the differential equations of motion of the servicer and debris object are integrated at the same time. This is not required in this scenario @@ -53,7 +53,7 @@ are independent of each other. If an effector is used that is connected to both spacecraft, then this step will allow the effector force and torque evaluations to be properly applied to all sync'd objects. -This simulation scripts illustrates how to use the :ref:`vizSupport` methods to record the simulation data such +This simulation scripts illustrates how to use the ``vizSupport`` methods to record the simulation data such that it can be viewed in the Vizard visualization. diff --git a/examples/scenarioIntegrators.py b/examples/scenarioIntegrators.py index c477cc91c..ffba64df3 100755 --- a/examples/scenarioIntegrators.py +++ b/examples/scenarioIntegrators.py @@ -7,9 +7,13 @@ Overview -------- +.. highlight:: python + This script illustrates how to setup different integration methods for a basic 3-DOF orbit scenario. -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioIntegrators.py diff --git a/examples/scenarioMagneticFieldCenteredDipole.py b/examples/scenarioMagneticFieldCenteredDipole.py index cf61d7d51..098afed59 100644 --- a/examples/scenarioMagneticFieldCenteredDipole.py +++ b/examples/scenarioMagneticFieldCenteredDipole.py @@ -7,6 +7,8 @@ Overview -------- +.. highlight:: python + This script sets up a 3-DOF spacecraft which is orbiting a planet that has a magnetic field. The purpose is to illustrate how to create and setup the centered dipole @@ -14,7 +16,9 @@ magnetic field at a spacecraft location. The orbit setup is similar to that used in :ref:`scenarioBasicOrbit`. -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioMagneticFieldCenteredDipole.py diff --git a/examples/scenarioMagneticFieldWMM.py b/examples/scenarioMagneticFieldWMM.py index 8ffd75f9e..fb029e450 100644 --- a/examples/scenarioMagneticFieldWMM.py +++ b/examples/scenarioMagneticFieldWMM.py @@ -7,6 +7,8 @@ Overview -------- +.. highlight:: python + This script sets up a 3-DOF spacecraft which is orbiting the with a magnetic field model. This scenario is similar to the centered dipole model :ref:`scenarioMagneticFieldCenteredDipole`, but here @@ -17,7 +19,9 @@ magnetic field at a spacecraft location. The orbit setup is similar to that used in :ref:`scenarioBasicOrbit`. -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioMagneticFieldWMM.py diff --git a/examples/scenarioSatelliteConstellation.py b/examples/scenarioSatelliteConstellation.py index bac0a64d9..981c5b6a7 100644 --- a/examples/scenarioSatelliteConstellation.py +++ b/examples/scenarioSatelliteConstellation.py @@ -12,10 +12,14 @@ uses the stand-alone Xmera architecture rather than using the ''examples/FormationBskSim`` or ``examples/MultiSatBskSim`` architectures for simultaneously simulating multiple spacecraft. -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioSatelliteConstellation.py +.. highlight:: python + When designing a satellite constellation, symmetry provides repeatable performance and makes design and operations simpler. One such symmetric constellation design methodology is the Walker constellation which consists of circular orbits in evenly spaced planes at a chosen inclination. Walker constellation layouts are fully specified by four parameters written as "i:T/P/F" where: diff --git a/examples/scenarioTAM.py b/examples/scenarioTAM.py index 5507656fe..d237d69f6 100644 --- a/examples/scenarioTAM.py +++ b/examples/scenarioTAM.py @@ -11,10 +11,14 @@ This script sets up a 3-DOF spacecraft which is orbiting a planet with a magnetic field. The orbit setup is similar to that used in :ref:`scenarioBasicOrbit`. -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioTAM.py +.. highlight:: python + Simulation Scenario Setup Details --------------------------------- The simulation layout is shown in the following illustration. A single simulation process is created diff --git a/examples/scenarioTAMcomparison.py b/examples/scenarioTAMcomparison.py index 3611c35c7..0427e2687 100644 --- a/examples/scenarioTAMcomparison.py +++ b/examples/scenarioTAMcomparison.py @@ -12,10 +12,14 @@ magnetic field representations, biases, and bounds to each. The orbit setup is similar to that used in :ref:`scenarioBasicOrbit`. -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioTAMcomparison.py +.. highlight:: python + Simulation Scenario Setup Details --------------------------------- The simulation layout is shown in the following illustration. A single simulation process is created which contains diff --git a/examples/scenarioTwoChargedSC.py b/examples/scenarioTwoChargedSC.py index 4018c6287..1bb4ce497 100644 --- a/examples/scenarioTwoChargedSC.py +++ b/examples/scenarioTwoChargedSC.py @@ -7,7 +7,7 @@ Overview -------- -Demonstrates the interaction between two charged spacecraft in a leader/follower configuration, the effect electrostatic forces/torques have on the separation of the two spacecrafts and how to visualize the simulation data in :ref:`Vizard `. The scenario demonstrates how to use :ref:`msmForceTorque` to calculate the electrostatic forces using the Multi-Sphere Method. Each spacecraft is represented by multiple spheres each with a designated location and radius. The locations and radii data is stored in ``GOESR_bus_80_sphs.csv``, however any appropriate csv file can be used. Both spacecraft have a negative charged potential. The purpose of this script is to show how to set up the Multi-Sphere Method for charged spacecraft and apply the external forces/torques to the spacecrafts as well as to show how to store the Xmera simulation data to be able to visualize both satellite's motions within the :ref:`Vizard ` application. +Demonstrates the interaction between two charged spacecraft in a leader/follower configuration, the effect electrostatic forces/torques have on the separation of the two spacecrafts and how to visualize the simulation data in ``Vizard``. The scenario demonstrates how to use :ref:`msmForceTorque` to calculate the electrostatic forces using the Multi-Sphere Method. Each spacecraft is represented by multiple spheres each with a designated location and radius. The locations and radii data is stored in ``GOESR_bus_80_sphs.csv``, however any appropriate csv file can be used. Both spacecraft have a negative charged potential. The purpose of this script is to show how to set up the Multi-Sphere Method for charged spacecraft and apply the external forces/torques to the spacecrafts as well as to show how to store the Xmera simulation data to be able to visualize both satellite's motions within the ``Vizard`` application. The script is found in the folder ``xmera/examples`` and executed by using:: diff --git a/examples/scenarioVariableTimeStepIntegrators.py b/examples/scenarioVariableTimeStepIntegrators.py index 85dea6c26..c766168ed 100644 --- a/examples/scenarioVariableTimeStepIntegrators.py +++ b/examples/scenarioVariableTimeStepIntegrators.py @@ -11,10 +11,14 @@ Both a fourth-order (RKF45) and a seventh-order (RKF78) integrators are used. For comparison, an RK4 integrator is also used. -The script is found in the folder ``xmera/examples`` and executed by using:: +The script is found in the folder ``xmera/examples`` and executed by using: + +.. code-block:: console python3 scenarioVariableTimeStepIntegrators.py +.. highlight:: python + For more information on how to setup different integrators, see :ref:`scenarioIntegrators`. When the simulation completes, a plot is shown for illustrating both the true and the numerically evaluated orbit. diff --git a/examples/scenarioVizPoint.py b/examples/scenarioVizPoint.py index 2835b4f8c..ac81f1a77 100755 --- a/examples/scenarioVizPoint.py +++ b/examples/scenarioVizPoint.py @@ -24,7 +24,7 @@ When the simulation completes 3 plots are shown for the MRP attitude history, the rate tracking errors, as well as the control torque vector. The ``run()`` method is setup to write out the -Vizard data file to sub-folder ``_VizFiles/scenarioVizPoint_UnityViz.bin``. By running :ref:`Vizard ` +Vizard data file to sub-folder ``_VizFiles/scenarioVizPoint_UnityViz.bin``. By running ``Vizard`` and playing back this data file you will see the custom camera view that is created as illustrated in the Vizard snapshot above. diff --git a/src/fswAlgorithms/attGuidance/celestialTwoBodyPoint/celestialTwoBodyPoint.rst b/src/fswAlgorithms/attGuidance/celestialTwoBodyPoint/celestialTwoBodyPoint.rst index 9bff3bf16..cab03256c 100644 --- a/src/fswAlgorithms/attGuidance/celestialTwoBodyPoint/celestialTwoBodyPoint.rst +++ b/src/fswAlgorithms/attGuidance/celestialTwoBodyPoint/celestialTwoBodyPoint.rst @@ -55,12 +55,12 @@ the spacecraft. .. _fig1_celestialTwoBodyPoint: .. figure:: _Documentation/Figures/fig1.pdf :align: center - name: fig:fig1 + :name: fig:fig1 -Illustration of the restricted two-body pointing reference frame -:math:`\mathcal{R}:\{ \hat{\mathbf r}_{1},\hat{\mathbf r}_{1}, \hat{\mathbf r}_{2} \}` -and the inertial frame -:math:`\mathcal{N}:\{ \hat{\mathbf n}_{1},\hat{\mathbf n}_{1}, \hat{\mathbf n}_{2} \}`. + Illustration of the restricted two-body pointing reference frame + :math:`\mathcal{R}:\{ \hat{\mathbf r}_{1},\hat{\mathbf r}_{1}, \hat{\mathbf r}_{2} \}` + and the inertial frame + :math:`\mathcal{N}:\{ \hat{\mathbf n}_{1},\hat{\mathbf n}_{1}, \hat{\mathbf n}_{2} \}`. Assuming knowledge of the position of the spacecraft :math:`\mathbf{r}_{B/N}` and the involved celestial bodies, diff --git a/src/fswAlgorithms/attGuidance/constrainedAttitudeManeuver/constrainedAttitudeManeuver.rst b/src/fswAlgorithms/attGuidance/constrainedAttitudeManeuver/constrainedAttitudeManeuver.rst index 51d047113..b61219a52 100644 --- a/src/fswAlgorithms/attGuidance/constrainedAttitudeManeuver/constrainedAttitudeManeuver.rst +++ b/src/fswAlgorithms/attGuidance/constrainedAttitudeManeuver/constrainedAttitudeManeuver.rst @@ -67,7 +67,7 @@ Two different cost functions are used by the :math:`A^*` algorithm to search a v The second is the effort-based cost function computed integrating the control torque norm over the interpolated trajectory obtained from a path., as explained in `R. Calaon and H. Schaub `__. In both cases, the final reference passed to the Attitude Reference Message consists in the interpolated curve obtained from the optimal path computed by :math:`A^*`, based on the chosen cost function. Interpolation is performed using the -routine in :ref:`BSpline`. +routine in ``BSpline``. Note that this module does not implement the constant angular rate norm routine described in `R. Calaon and H. Schaub `__. The attitude, rates and accelerations provided to the Attitude Reference Message are those obtained directly from the BSpline interpolation. diff --git a/src/fswAlgorithms/attGuidance/mrpRotation/mrpRotation.rst b/src/fswAlgorithms/attGuidance/mrpRotation/mrpRotation.rst index ec5d8d734..e4eed1701 100644 --- a/src/fswAlgorithms/attGuidance/mrpRotation/mrpRotation.rst +++ b/src/fswAlgorithms/attGuidance/mrpRotation/mrpRotation.rst @@ -146,7 +146,7 @@ The ``mrpRotation`` module has the following design goals - **Flexible Setup**: The desired rotation state can be described through an initial MRP and angular velocity vector specified in module - internal variables, or read in through a Xmera :ref:`AttStateMsg` + internal variables, or read in through a Xmera :ref:`AttStateMsgPayload` message. Module Assumptions and Limitations diff --git a/src/fswAlgorithms/attGuidance/sunSearch/sunSearch.rst b/src/fswAlgorithms/attGuidance/sunSearch/sunSearch.rst index a411b693e..8dc05da5b 100644 --- a/src/fswAlgorithms/attGuidance/sunSearch/sunSearch.rst +++ b/src/fswAlgorithms/attGuidance/sunSearch/sunSearch.rst @@ -73,7 +73,9 @@ which indicates that adding a coasting arc to meet the requirement on the angula User Guide ---------- -The required module configuration is:: +The required module configuration is: + +.. code-block:: python attGuid = sunSearch.SunSearch() diff --git a/src/fswAlgorithms/attGuidance/sunSearch_C/sunSearch_C.rst b/src/fswAlgorithms/attGuidance/sunSearch_C/sunSearch_C.rst index 97b336d38..5c2f77652 100644 --- a/src/fswAlgorithms/attGuidance/sunSearch_C/sunSearch_C.rst +++ b/src/fswAlgorithms/attGuidance/sunSearch_C/sunSearch_C.rst @@ -73,7 +73,9 @@ which indicates that adding a coasting arc to meet the requirement on the angula User Guide ---------- -The required module configuration is:: +The required module configuration is: + +.. code-block:: python attGuid = sunSearch.SunSearch() attGuid.setSlewTime(90, 90, 90) # [s] diff --git a/src/fswAlgorithms/effectorInterfaces/prescribedRot1DOF/prescribedRot1DOF.rst b/src/fswAlgorithms/effectorInterfaces/prescribedRot1DOF/prescribedRot1DOF.rst index 60f461e93..fad730653 100644 --- a/src/fswAlgorithms/effectorInterfaces/prescribedRot1DOF/prescribedRot1DOF.rst +++ b/src/fswAlgorithms/effectorInterfaces/prescribedRot1DOF/prescribedRot1DOF.rst @@ -1,171 +1,175 @@ -Executive Summary ------------------ -This module profiles a :ref:`PrescribedRotationMsgPayload` message for a specified 1 DOF rotation for a secondary -prescribed rigid body connected to a rigid spacecraft hub at a hub-fixed location, :math:`\mathcal{M}`. The body -frame for the prescribed body is designated by the frame :math:`\mathcal{F}`. Accordingly, the prescribed states for the -secondary body are written with respect to the mount frame, :math:`\mathcal{M}`. The prescribed states profiled -in this module are: ``omega_FM_F``, ``omegaPrime_FM_F``, and ``sigma_FM``. - -To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` -dynamics module in order to profile the rotational states of the secondary body. A second kinematic profiler -module must also be connected to the prescribed motion dynamics module to profile the translational states of the -prescribed body. The required rotation is determined from the user-specified scalar maximum angular acceleration -for the rotation :math:`\alpha_{\text{max}}`, prescribed body's initial attitude with respect to the mount frame -as the Principal Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\textbf{{e}}}_0)`, and the prescribed body's -reference attitude with respect to the mount frame as the Principal Rotation Vector -``prv_F1M`` :math:`(\Phi_1, \hat{\textbf{{e}}}_1)`. - -The maximum scalar angular acceleration is applied constant and positively for the first half of the rotation and -constant negatively for the second half of the rotation. The resulting angular velocity of the prescribed body is -linear, approaching a maximum magnitude halfway through the rotation and ending with zero residual velocity. -The corresponding angle the prescribed body moves through during the rotation is parabolic in time. - -.. warning:: - This module is now deprecated. See the :ref:`PrescribedRotation1DOF` module that replaces this module. - -Message Connection Descriptions -------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description -provides information on what this message is used for. - -.. list-table:: Module I/O Messages - :widths: 25 25 50 - :header-rows: 1 - - * - Msg Variable Name - - Msg Type - - Description - * - spinningBodyInMsg - - :ref:`HingedRigidBodyMsgPayload` - - input msg with the scalar spinning body rotational reference states - * - spinningBodyOutMsg - - :ref:`HingedRigidBodyMsgPayload` - - output message with the profiled scalar spinning body rotational states - * - prescribedMotionOutMsg - - :ref:`PrescribedRotationMsgPayload` - - output message with the profiled prescribed spinning body rotational states - - - -Detailed Module Description ---------------------------- -This 1 DOF rotational motion kinematic profiler module is written to profile spinning body motion with respect to a -body-fixed mount frame. The inputs to the profiler are the scalar maximum angular acceleration for the rotation -:math:`\alpha_{\text{max}}`, the prescribed body's initial attitude with respect to the mount frame as the Principal -Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\textbf{{e}}}_0)`, and the prescribed body's reference attitude with -respect to the mount frame as the Principal Rotation Vector ``prv_F1M`` :math:`(\Phi_1, \hat{\textbf{{e}}}_1)`. -The prescribed body is assumed to be non-rotating at the beginning of the rotation. - -Subtracting the initial principal rotation vector from the reference principal rotation vector gives the required -rotation angle and axis for the rotation: - -.. math:: - \Phi_{\text{ref}} = 2 \cos^{-1} \left ( \cos \frac{\Phi_1}{2} \cos \frac{\Phi_0}{2} + \sin \frac{\Phi_1}{2} \sin \frac {\Phi_0}{2} \hat{\textbf{{e}}}_1 \cdot \hat{\textbf{{e}}}_0 \right ) - -.. math:: - \hat{\textbf{{e}}} = \frac{\cos \frac{\Phi_0}{2} \sin \frac{\Phi_1}{2} \hat{\textbf{{e}}}_1 - \cos \frac{\Phi_1}{2} \sin \frac{\Phi_0}{2} \hat{\textbf{{e}}}_0 + \sin \frac{\Phi_1}{2} \sin \frac{\Phi_0}{2} \hat{\textbf{{e}}}_1 \times \hat{\textbf{{e}}}_0 }{\sin \frac{\Phi_{\text{ref}}}{2}} - -During the first half of the rotation, the prescribed body is constantly accelerated with the given maximum -angular acceleration. The prescribed body's angular velocity increases linearly during the acceleration phase and -reaches a maximum magnitude halfway through the rotation. The switch time :math:`t_s` is the simulation time -halfway through the rotation: - -.. math:: - t_s = t_0 + \frac{\Delta t}{2} - -where the time required for the rotation :math:`\Delta t` is determined using the inputs to the profiler: - -.. math:: - \Delta t = t_f - t_0 = 2 \sqrt{ \Phi_{\text{ref}} / \ddot{\Phi}_{\text{max}}} - -The resulting trajectory of the angle :math:`\Phi` swept during the first half of the rotation is parabolic. The profiled -motion is concave upwards if the reference angle :math:`\Phi_{\text{ref}}` is greater than zero. If the converse is true, -the profiled motion is instead concave downwards. The described motion during the first half of the rotation -is characterized by the expressions: - -.. math:: - \omega_{\mathcal{F} / \mathcal{M}}(t) = \alpha_{\text{max}} - -.. math:: - \dot{\Phi}(t) = \alpha_{\text{max}} (t - t_0) - -.. math:: - \Phi(t) = c_1 (t - t_0)^2 - -where - -.. math:: - c_1 = \frac{\Phi_{\text{ref}}}{2(t_s - t_0)^2} - -Similarly, the second half of the rotation decelerates the prescribed body constantly until it reaches a -non-rotating state. The prescribed body angular velocity decreases linearly from its maximum magnitude back to zero. -The trajectory swept during the second half of the rotation is quadratic and concave downwards if the reference angle -:math:`\Phi_{\text{ref}}` is positive. If :math:`\Phi_{\text{ref}}` is negative, the profiled motion is instead -concave upwards. The described motion during the second half of the rotation is characterized by the expressions: - -.. math:: - \ddot{\Phi}(t) = -\alpha_{\text{max}} - -.. math:: - \dot{\Phi}(t) = \alpha_{\text{max}} (t - t_f) - -.. math:: - \Phi(t) = c_2 (t - t_f)^2 + \Phi_{\text{ref}} - - where - -.. math:: - c_2 = \frac{\Phi_{\text{ref}}}{2(t_s - t_f)^2} - -Module Testing -^^^^^^^^^^^^^^ -The unit test for this module ensures that the profiled 1 DOF rotation is properly computed for a series of -initial and reference PRV angles and maximum angular accelerations. The final prescribed angle ``theta_FM_Final`` -and angular velocity magnitude ``thetaDot_Final`` are compared with the reference values ``theta_Ref`` and -``thetaDot_Ref``, respectively. - -User Guide ----------- -The user-configurable inputs to the profiler are the scalar maximum angular acceleration for the rotation -:math:`\alpha_{\text{max}}`, the prescribed body's initial attitude with respect to the mount frame as the Principal -Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\textbf{{e}}}_0)`, and the prescribed body's reference attitude with -respect to the mount frame as the Principal Rotation Vector ``prv_F1M`` :math:`(\Phi_1, \hat{\textbf{{e}}}_1)`. - -This module provides two output messages in the form of :ref:`HingedRigidBodyMsgPayload` and -:ref:`PrescribedRotationMsgPayload`. The first message describes the spinning body's scalar rotational states relative -to the body-fixed mount frame. The second prescribed rotational motion output message can be connected to the -:ref:`PrescribedMotionStateEffector` dynamics module to directly profile a state effector's rotational motion. Note -that a separate translational profiler module must also be connected to the prescribed motion dynamics module to fully -define the kinematic motion of the prescribed body. - -This section is to outline the steps needed to setup a prescribed 1 DOF rotational module in python using Xmera. - -#. Import the prescribedRot1DOF class:: - - from Xmera.fswAlgorithms import prescribedRot1DOF - -#. Create an instantiation of a prescribed rotational 1 DOF C module and the associated C++ container:: - - PrescribedRot1DOF = prescribedRot1DOF.prescribedRot1DOF() - PrescribedRot1DOF.modelTag = "prescribedRot1DOF" - -#. Define all of the configuration data associated with the module. For example:: - - thetaInit = 0.0 # [rad] - rotAxis_M = np.array([1.0, 0.0, 0.0]) - prvInit_FM = thetaInit * rotAxisM - PrescribedRot1DOF.rotAxis_M = rotAxis_M - PrescribedRot1DOF.thetaDDotMax = 0.01 # [rad/s^2] - PrescribedRot1DOF.omega_FM_F = np.array([0.0, 0.0, 0.0]) - PrescribedRot1DOF.omegaPrime_FM_F = np.array([0.0, 0.0, 0.0]) - PrescribedRot1DOF.sigma_FM = rbk.PRV2MRP(prvInit_FM) - -The user is required to set the above configuration data parameters, as they are not initialized in the module. - -#. Make sure to connect the required messages for this module. - -#. Add the module to the task list:: - - unitTestSim.AddModelToTask(unitTaskName, PrescribedRot1DOF) +Executive Summary +----------------- +This module profiles a :ref:`PrescribedRotationMsgPayload` message for a specified 1 DOF rotation for a secondary +prescribed rigid body connected to a rigid spacecraft hub at a hub-fixed location, :math:`\mathcal{M}`. The body +frame for the prescribed body is designated by the frame :math:`\mathcal{F}`. Accordingly, the prescribed states for the +secondary body are written with respect to the mount frame, :math:`\mathcal{M}`. The prescribed states profiled +in this module are: ``omega_FM_F``, ``omegaPrime_FM_F``, and ``sigma_FM``. + +To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` +dynamics module in order to profile the rotational states of the secondary body. A second kinematic profiler +module must also be connected to the prescribed motion dynamics module to profile the translational states of the +prescribed body. The required rotation is determined from the user-specified scalar maximum angular acceleration +for the rotation :math:`\alpha_{\text{max}}`, prescribed body's initial attitude with respect to the mount frame +as the Principal Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\textbf{{e}}}_0)`, and the prescribed body's +reference attitude with respect to the mount frame as the Principal Rotation Vector +``prv_F1M`` :math:`(\Phi_1, \hat{\textbf{{e}}}_1)`. + +The maximum scalar angular acceleration is applied constant and positively for the first half of the rotation and +constant negatively for the second half of the rotation. The resulting angular velocity of the prescribed body is +linear, approaching a maximum magnitude halfway through the rotation and ending with zero residual velocity. +The corresponding angle the prescribed body moves through during the rotation is parabolic in time. + +.. warning:: + This module is now deprecated. See the :ref:`PrescribedRotation1DOF` module that replaces this module. + +Message Connection Descriptions +------------------------------- +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description +provides information on what this message is used for. + +.. list-table:: Module I/O Messages + :widths: 25 25 50 + :header-rows: 1 + + * - Msg Variable Name + - Msg Type + - Description + * - spinningBodyInMsg + - :ref:`HingedRigidBodyMsgPayload` + - input msg with the scalar spinning body rotational reference states + * - spinningBodyOutMsg + - :ref:`HingedRigidBodyMsgPayload` + - output message with the profiled scalar spinning body rotational states + * - prescribedMotionOutMsg + - :ref:`PrescribedRotationMsgPayload` + - output message with the profiled prescribed spinning body rotational states + + + +Detailed Module Description +--------------------------- +This 1 DOF rotational motion kinematic profiler module is written to profile spinning body motion with respect to a +body-fixed mount frame. The inputs to the profiler are the scalar maximum angular acceleration for the rotation +:math:`\alpha_{\text{max}}`, the prescribed body's initial attitude with respect to the mount frame as the Principal +Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\textbf{{e}}}_0)`, and the prescribed body's reference attitude with +respect to the mount frame as the Principal Rotation Vector ``prv_F1M`` :math:`(\Phi_1, \hat{\textbf{{e}}}_1)`. +The prescribed body is assumed to be non-rotating at the beginning of the rotation. + +Subtracting the initial principal rotation vector from the reference principal rotation vector gives the required +rotation angle and axis for the rotation: + +.. math:: + \Phi_{\text{ref}} = 2 \cos^{-1} \left ( \cos \frac{\Phi_1}{2} \cos \frac{\Phi_0}{2} + \sin \frac{\Phi_1}{2} \sin \frac {\Phi_0}{2} \hat{\textbf{{e}}}_1 \cdot \hat{\textbf{{e}}}_0 \right ) + +.. math:: + \hat{\textbf{{e}}} = \frac{\cos \frac{\Phi_0}{2} \sin \frac{\Phi_1}{2} \hat{\textbf{{e}}}_1 - \cos \frac{\Phi_1}{2} \sin \frac{\Phi_0}{2} \hat{\textbf{{e}}}_0 + \sin \frac{\Phi_1}{2} \sin \frac{\Phi_0}{2} \hat{\textbf{{e}}}_1 \times \hat{\textbf{{e}}}_0 }{\sin \frac{\Phi_{\text{ref}}}{2}} + +During the first half of the rotation, the prescribed body is constantly accelerated with the given maximum +angular acceleration. The prescribed body's angular velocity increases linearly during the acceleration phase and +reaches a maximum magnitude halfway through the rotation. The switch time :math:`t_s` is the simulation time +halfway through the rotation: + +.. math:: + t_s = t_0 + \frac{\Delta t}{2} + +where the time required for the rotation :math:`\Delta t` is determined using the inputs to the profiler: + +.. math:: + \Delta t = t_f - t_0 = 2 \sqrt{ \Phi_{\text{ref}} / \ddot{\Phi}_{\text{max}}} + +The resulting trajectory of the angle :math:`\Phi` swept during the first half of the rotation is parabolic. The profiled +motion is concave upwards if the reference angle :math:`\Phi_{\text{ref}}` is greater than zero. If the converse is true, +the profiled motion is instead concave downwards. The described motion during the first half of the rotation +is characterized by the expressions: + +.. math:: + \omega_{\mathcal{F} / \mathcal{M}}(t) = \alpha_{\text{max}} + +.. math:: + \dot{\Phi}(t) = \alpha_{\text{max}} (t - t_0) + +.. math:: + \Phi(t) = c_1 (t - t_0)^2 + +where + +.. math:: + c_1 = \frac{\Phi_{\text{ref}}}{2(t_s - t_0)^2} + +Similarly, the second half of the rotation decelerates the prescribed body constantly until it reaches a +non-rotating state. The prescribed body angular velocity decreases linearly from its maximum magnitude back to zero. +The trajectory swept during the second half of the rotation is quadratic and concave downwards if the reference angle +:math:`\Phi_{\text{ref}}` is positive. If :math:`\Phi_{\text{ref}}` is negative, the profiled motion is instead +concave upwards. The described motion during the second half of the rotation is characterized by the expressions: + +.. math:: + \ddot{\Phi}(t) = -\alpha_{\text{max}} + +.. math:: + \dot{\Phi}(t) = \alpha_{\text{max}} (t - t_f) + +.. math:: + \Phi(t) = c_2 (t - t_f)^2 + \Phi_{\text{ref}} + + where + +.. math:: + c_2 = \frac{\Phi_{\text{ref}}}{2(t_s - t_f)^2} + +Module Testing +^^^^^^^^^^^^^^ +The unit test for this module ensures that the profiled 1 DOF rotation is properly computed for a series of +initial and reference PRV angles and maximum angular accelerations. The final prescribed angle ``theta_FM_Final`` +and angular velocity magnitude ``thetaDot_Final`` are compared with the reference values ``theta_Ref`` and +``thetaDot_Ref``, respectively. + +User Guide +---------- +The user-configurable inputs to the profiler are the scalar maximum angular acceleration for the rotation +:math:`\alpha_{\text{max}}`, the prescribed body's initial attitude with respect to the mount frame as the Principal +Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\textbf{{e}}}_0)`, and the prescribed body's reference attitude with +respect to the mount frame as the Principal Rotation Vector ``prv_F1M`` :math:`(\Phi_1, \hat{\textbf{{e}}}_1)`. + +This module provides two output messages in the form of :ref:`HingedRigidBodyMsgPayload` and +:ref:`PrescribedRotationMsgPayload`. The first message describes the spinning body's scalar rotational states relative +to the body-fixed mount frame. The second prescribed rotational motion output message can be connected to the +:ref:`PrescribedMotionStateEffector` dynamics module to directly profile a state effector's rotational motion. Note +that a separate translational profiler module must also be connected to the prescribed motion dynamics module to fully +define the kinematic motion of the prescribed body. + +This section is to outline the steps needed to setup a prescribed 1 DOF rotational module in python using Xmera. + +#. Import the prescribedRot1DOF class: + +.. code-block:: python + + from Xmera.fswAlgorithms import prescribedRot1DOF + +#. Create an instantiation of a prescribed rotational 1 DOF C module and the associated C++ container:: + + PrescribedRot1DOF = prescribedRot1DOF.prescribedRot1DOF() + PrescribedRot1DOF.modelTag = "prescribedRot1DOF" + +#. Define all of the configuration data associated with the module. For example: + +.. code-block:: python + + thetaInit = 0.0 # [rad] + rotAxis_M = np.array([1.0, 0.0, 0.0]) + prvInit_FM = thetaInit * rotAxisM + PrescribedRot1DOF.rotAxis_M = rotAxis_M + PrescribedRot1DOF.thetaDDotMax = 0.01 # [rad/s^2] + PrescribedRot1DOF.omega_FM_F = np.array([0.0, 0.0, 0.0]) + PrescribedRot1DOF.omegaPrime_FM_F = np.array([0.0, 0.0, 0.0]) + PrescribedRot1DOF.sigma_FM = rbk.PRV2MRP(prvInit_FM) + +The user is required to set the above configuration data parameters, as they are not initialized in the module. + +#. Make sure to connect the required messages for this module. + +#. Add the module to the task list:: + + unitTestSim.AddModelToTask(unitTaskName, PrescribedRot1DOF) diff --git a/src/fswAlgorithms/effectorInterfaces/prescribedRot2DOF/prescribedRot2DOF.rst b/src/fswAlgorithms/effectorInterfaces/prescribedRot2DOF/prescribedRot2DOF.rst index 8e7bf5570..799364f2c 100644 --- a/src/fswAlgorithms/effectorInterfaces/prescribedRot2DOF/prescribedRot2DOF.rst +++ b/src/fswAlgorithms/effectorInterfaces/prescribedRot2DOF/prescribedRot2DOF.rst @@ -1,191 +1,195 @@ -Executive Summary ------------------ -This module profiles a :ref:`PrescribedRotationMsgPayload` message for a specified 2 DOF rotation -for a secondary rigid body connected to a rigid spacecraft hub at a hub-fixed location, :math:`\mathcal{M}`. The body -frame for the prescribed body is designated by the frame :math:`\mathcal{F}`. Accordingly, the prescribed states for the -secondary body are written with respect to the mount frame, :math:`\mathcal{M}`. The prescribed states profiled -in this module are: ``omega_FM_F``, ``omegaPrime_FM_F``, and ``sigma_FM``. - -It should be noted that although the inputs to this module are two consecutive rotation angles and axes, the resulting -rotation that is profiled is a 1 DOF rotation. The module converts two given reference angles and their corresponding -rotation axes for the rotation to a single 1 DOF rotation for the rotation. Simple Principal Rotation Vector (PRV) -addition is used on the two given reference PRVs to determine the single PRV required for the rotation. - -To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` -dynamics module in order to profile the rotational states of the secondary body. A second kinematic profiler module -must also be connected to the prescribed motion dynamics module to profile the translational states of the prescribed -body. The required rotation is determined from the user-specified scalar maximum angular acceleration for the rotation, -:math:`\alpha_{\text{max}}`, the spinning body's initial attitude with respect to the mount frame as the Principal -Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\boldsymbol{e}}_0)`, and two reference Principal Rotation Vectors -for the rotation, ``prv_F1F0`` :math:`(\Phi_{1a}, \hat{\boldsymbol{e}}_{1a})` and ``prv_F2F1`` -:math:`(\Phi_{1b}, \hat{\boldsymbol{e}}_{1b})`. - -The maximum scalar angular acceleration is applied constant and positively for the first half of the rotation and -constant negatively for the second half of the rotation. The resulting angular velocity of the prescribed body is -linear, approaching a maximum magnitude halfway through the rotation and ending with zero residual velocity. -The corresponding angle the prescribed body moves through during the rotation is parabolic in time. - -Message Connection Descriptions -------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description -provides information on what this message is used for. - -.. list-table:: Module I/O Messages - :widths: 25 25 50 - :header-rows: 1 - - * - Msg Variable Name - - Msg Type - - Description - * - spinningBodyRef1InMsg - - :ref:`HingedRigidBodyMsgPayload` - - input msg with the scalar spinning body rotational reference states for the first rotation - * - spinningBodyRef2InMsg - - :ref:`HingedRigidBodyMsgPayload` - - input msg with the scalar spinning body rotational reference states for the second rotation - * - prescribedMotionOutMsg - - :ref:`PrescribedRotationMsgPayload` - - output message with the prescribed spinning body rotational states - - -Detailed Module Description ---------------------------- -This 2 DOF rotational motion kinematic profiler module converts a given 2 DOF rotation to a single 1 DOF rotation -and profiles the required spinning body rotational motion with respect to a body-fixed mount frame for the -rotation. The inputs to the profiler are the maximum angular acceleration for the rotation, -:math:`\alpha_{\text{max}}`, the spinning body's initial attitude with respect to the mount frame as the Principal -Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\boldsymbol{e}}_0)`, and two reference Principal Rotation Vectors -for the rotation, ``prv_F1F0`` :math:`(\Phi_{1a}, \hat{\boldsymbol{e}}_{1a})` and ``prv_F2F1`` -:math:`(\Phi_{1b}, \hat{\boldsymbol{e}}_{1b})`. - -The module first converts the two given reference PRVs to a single PRV, ``prv_F2M`` that represents the final spinning -body attitude with respect to the body-fixed mount frame: - -.. math:: - \Phi_2 = 2 \cos^{-1} \left ( \cos \frac{\Phi_{1a}}{2} \cos \frac{\Phi_{1b}}{2} - \sin \frac{\Phi_{1a}}{2} \sin \frac {\Phi_{1b}}{2} \ \hat{\boldsymbol{e}}_{1a} \cdot \hat{\boldsymbol{e}}_{1b} \right ) - -.. math:: - \hat{\boldsymbol{e}}_2 = \frac{\cos \frac{\Phi_{1b}}{2} \sin \frac{\Phi_{1a}}{2} \ \hat{\boldsymbol{e}}_{1a} + \cos \frac{\Phi_{1a}}{2} \sin \frac{\Phi_{1b}}{2} \ \boldsymbol{e}_{1b} + \sin \frac{\Phi_{1a}}{2} \sin \frac{\Phi_{1b}}{2} \ \hat{\boldsymbol{e}}_{1a} \times \hat{\boldsymbol{e}}_{1b} }{\sin \frac{\Phi_2}{2}} - -Subtracting the initial Principal Rotation Vector ``prv_F0M`` from the found reference PRV ``prv_F2M`` gives the -required PRV for the rotation, ``prv_F2F0``: - -.. math:: - \Phi_{\text{ref}} = \Delta \Phi = 2 \cos^{-1} \left ( \cos \frac{\Phi_2}{2} \cos \frac{\Phi_0}{2} + \sin \frac{\Phi_2}{2} \sin \frac {\Phi_0}{2} \ \hat{\boldsymbol{e}}_2 \cdot \hat{\boldsymbol{e}}_0 \right ) - -.. math:: - \hat{\boldsymbol{e}}_3 = \frac{\cos \frac{\Phi_0}{2} \sin \frac{\Phi_2}{2} \ \hat{\boldsymbol{e}}_2 - \cos \frac{\Phi_2}{2} \sin \frac{\Phi_0}{2} \ \hat{\boldsymbol{e}}_0 + \sin \frac{\Phi_2}{2} \sin \frac{\Phi_0}{2} \ \hat{\boldsymbol{e}}_2 \times \hat{\boldsymbol{e}}_0 }{\sin \frac{\Delta \Phi}{2}} - -Note that the initial PRV angle, :math:`\Phi_0` is reset to zero for consecutive rotations so that the -reference PRV angle, :math:`\Phi_{\text{ref}}` is always taken as the full angle to be swept during the rotation. - -During the first half of the rotation, the spinning body is constantly accelerated with the given maximum -angular acceleration. The spinning body's angular velocity increases linearly during the acceleration phase and reaches -a maximum magnitude halfway through the rotation. The switch time, :math:`t_s` is the simulation time halfway -through the rotation: - -.. math:: - t_s = t_0 + \frac{\Delta t}{2} - -where the time required for the rotation, :math:`\Delta t` is determined using the found PRV angle for the rotation: - -.. math:: - \Delta t = t_f - t_0 = 2\sqrt{ \Phi_{\text{ref}} / \alpha_{\text{max}}} - -The resulting trajectory of the angle :math:`\Phi` swept during the first half of the rotation is quadratic. The -profiled motion is concave upwards if the reference angle, :math:`\Phi_{\text{ref}}` is greater than zero. If the -reference angle is negative, the profiled motion is instead concave downwards. The described motion during the first -half of the rotation is characterized by the expressions: - -.. math:: - \ddot{\Phi}(t) = \alpha_{\text{max}} - -.. math:: - \dot{\Phi}(t) = \alpha_{\text{max}} (t - t_0) + \dot{\Phi}(t_0) - -.. math:: - \Phi(t) = a (t - t_0)^2 - -where - -.. math:: - a = \frac{ \frac{1}{2} \Phi_{\text{ref}}}{(t_s - t_0)^2} - -Similarly, the second half of the rotation decelerates the spinning body constantly until it reaches a -non-rotating state. The spinning body's angular velocity decreases linearly from its maximum magnitude back to zero. -The trajectory swept during the second half of the rotation is quadratic and concave downwards if the reference angle, -:math:`\Phi_{\text{ref}}` is greater than zero. If the reference angle is negative, the profiled motion is instead -concave upwards. The described motion during the second half of the rotation is characterized by the -expressions: - -.. math:: - \ddot{\Phi}(t) = -\alpha_{\text{max}} - -.. math:: - \dot{\Phi}(t) = \alpha_{\text{max}} (t - t_f) - -.. math:: - \Phi(t) = b (t - t_f)^2 + \Phi_{\text{ref}} - -where - -.. math:: - b = \frac{ \frac{1}{2} \Phi_{\text{ref}}}{(t_s - t_f)^2} - - -Module Testing -^^^^^^^^^^^^^^ -The unit test for this module simulates TWO consecutive 2 DOF rotational attitude maneuvers for a secondary rigid body -connected to a rigid spacecraft hub. Two maneuvers are simulated to ensure that the module correctly updates the -required relative PRV attitude when a new attitude reference message is written. The unit test checks that the prescribed -body's MRP attitude converges to both reference attitudes for a series of initial and reference attitudes and -maximum angular accelerations. (``sigma_FM_Final1`` is checked to converge to ``sigma_FM_Ref1``, and -``sigma_FM_Final2`` is checked to converge to ``sigma_FM_Ref2``). Additionally, the prescribed body's final angular -velocity magnitude ``thetaDot_Final`` is checked for convergence to the reference angular velocity magnitude, -``thetaDot_Ref``. - - -User Guide ----------- -The user-configurable inputs to the profiler are the maximum angular acceleration for the rotation, -:math:`\alpha_{\text{max}}`, the spinning body's initial attitude with respect to the mount frame as the Principal -Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\boldsymbol{e}}_0)`, and two reference Principal Rotation Vectors for -the rotation, ``prv_F1F0`` :math:`(\Phi_{1a}, \hat{\boldsymbol{e}}_{1a})` and ``prv_F2F1`` -:math:`(\Phi_{1b}, \hat{\boldsymbol{e}}_{1b})`. - -This module provides a single output message in the form of :ref:`prescribedRotationMsgPayload`. This prescribed -motion output message can be connected to the :ref:`prescribedMotionStateEffector` dynamics module to directly profile -a state effector's rotational motion. Note that a separate translational profiler module must also be connected to -the prescribed motion dynamics module to fully define the kinematic motion of the prescribed body. - -This section is to outline the steps needed to setup a prescribed 2 DOF rotational module in python using Xmera. - -#. Import the prescribedRot1DOF class:: - - from Xmera.fswAlgorithms import prescribedRot2DOF - -#. Create an instantiation of a prescribed rotational 2 DOF C module and the associated C++ container:: - - PrescribedRot2DOF = prescribedRot2DOF.prescribedRot2DOF() - PrescribedRot2DOF.modelTag = "PrescribedRot2DOF" - -#. Define all of the configuration data associated with the module. For example:: - - rotAxis1_M = np.array([0.0, 1.0, 0.0]) # Rotation axis for the first reference rotation angle, thetaRef1a - rotAxis2_F1 = np.array([0.0, 0.0, 1.0]) # Rotation axis for the second reference rotation angle, thetaRef2a - PrescribedRot2DOF.rotAxis1_M = rotAxis1_M - PrescribedRot2DOF.rotAxis2_F1 = rotAxis2_F1 - PrescribedRot2DOF.phiDDotMax = phiDDotMax - PrescribedRot2DOF.omega_FM_F = np.array([0.0, 0.0, 0.0]) # [rad/s] Angular velocity of frame F relative to frame M in F frame components - PrescribedRot2DOF.omegaPrime_FM_F = np.array([0.0, 0.0, 0.0]) # [rad/s^2] B frame time derivative of omega_FB_F in F frame components - PrescribedRot2DOF.sigma_FM = np.array([0.0, 0.0, 0.0]) # MRP attitude of frame F relative to frame M - -The user is required to set the above configuration data parameters, as they are not initialized in the module. - -#. Make sure to connect the required messages for this module. - -#. Add the module to the task list:: - - unitTestSim.AddModelToTask(unitTaskName, PrescribedRot2DOF) +Executive Summary +----------------- +This module profiles a :ref:`PrescribedRotationMsgPayload` message for a specified 2 DOF rotation +for a secondary rigid body connected to a rigid spacecraft hub at a hub-fixed location, :math:`\mathcal{M}`. The body +frame for the prescribed body is designated by the frame :math:`\mathcal{F}`. Accordingly, the prescribed states for the +secondary body are written with respect to the mount frame, :math:`\mathcal{M}`. The prescribed states profiled +in this module are: ``omega_FM_F``, ``omegaPrime_FM_F``, and ``sigma_FM``. + +It should be noted that although the inputs to this module are two consecutive rotation angles and axes, the resulting +rotation that is profiled is a 1 DOF rotation. The module converts two given reference angles and their corresponding +rotation axes for the rotation to a single 1 DOF rotation for the rotation. Simple Principal Rotation Vector (PRV) +addition is used on the two given reference PRVs to determine the single PRV required for the rotation. + +To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` +dynamics module in order to profile the rotational states of the secondary body. A second kinematic profiler module +must also be connected to the prescribed motion dynamics module to profile the translational states of the prescribed +body. The required rotation is determined from the user-specified scalar maximum angular acceleration for the rotation, +:math:`\alpha_{\text{max}}`, the spinning body's initial attitude with respect to the mount frame as the Principal +Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\boldsymbol{e}}_0)`, and two reference Principal Rotation Vectors +for the rotation, ``prv_F1F0`` :math:`(\Phi_{1a}, \hat{\boldsymbol{e}}_{1a})` and ``prv_F2F1`` +:math:`(\Phi_{1b}, \hat{\boldsymbol{e}}_{1b})`. + +The maximum scalar angular acceleration is applied constant and positively for the first half of the rotation and +constant negatively for the second half of the rotation. The resulting angular velocity of the prescribed body is +linear, approaching a maximum magnitude halfway through the rotation and ending with zero residual velocity. +The corresponding angle the prescribed body moves through during the rotation is parabolic in time. + +Message Connection Descriptions +------------------------------- +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description +provides information on what this message is used for. + +.. list-table:: Module I/O Messages + :widths: 25 25 50 + :header-rows: 1 + + * - Msg Variable Name + - Msg Type + - Description + * - spinningBodyRef1InMsg + - :ref:`HingedRigidBodyMsgPayload` + - input msg with the scalar spinning body rotational reference states for the first rotation + * - spinningBodyRef2InMsg + - :ref:`HingedRigidBodyMsgPayload` + - input msg with the scalar spinning body rotational reference states for the second rotation + * - prescribedMotionOutMsg + - :ref:`PrescribedRotationMsgPayload` + - output message with the prescribed spinning body rotational states + + +Detailed Module Description +--------------------------- +This 2 DOF rotational motion kinematic profiler module converts a given 2 DOF rotation to a single 1 DOF rotation +and profiles the required spinning body rotational motion with respect to a body-fixed mount frame for the +rotation. The inputs to the profiler are the maximum angular acceleration for the rotation, +:math:`\alpha_{\text{max}}`, the spinning body's initial attitude with respect to the mount frame as the Principal +Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\boldsymbol{e}}_0)`, and two reference Principal Rotation Vectors +for the rotation, ``prv_F1F0`` :math:`(\Phi_{1a}, \hat{\boldsymbol{e}}_{1a})` and ``prv_F2F1`` +:math:`(\Phi_{1b}, \hat{\boldsymbol{e}}_{1b})`. + +The module first converts the two given reference PRVs to a single PRV, ``prv_F2M`` that represents the final spinning +body attitude with respect to the body-fixed mount frame: + +.. math:: + \Phi_2 = 2 \cos^{-1} \left ( \cos \frac{\Phi_{1a}}{2} \cos \frac{\Phi_{1b}}{2} - \sin \frac{\Phi_{1a}}{2} \sin \frac {\Phi_{1b}}{2} \ \hat{\boldsymbol{e}}_{1a} \cdot \hat{\boldsymbol{e}}_{1b} \right ) + +.. math:: + \hat{\boldsymbol{e}}_2 = \frac{\cos \frac{\Phi_{1b}}{2} \sin \frac{\Phi_{1a}}{2} \ \hat{\boldsymbol{e}}_{1a} + \cos \frac{\Phi_{1a}}{2} \sin \frac{\Phi_{1b}}{2} \ \boldsymbol{e}_{1b} + \sin \frac{\Phi_{1a}}{2} \sin \frac{\Phi_{1b}}{2} \ \hat{\boldsymbol{e}}_{1a} \times \hat{\boldsymbol{e}}_{1b} }{\sin \frac{\Phi_2}{2}} + +Subtracting the initial Principal Rotation Vector ``prv_F0M`` from the found reference PRV ``prv_F2M`` gives the +required PRV for the rotation, ``prv_F2F0``: + +.. math:: + \Phi_{\text{ref}} = \Delta \Phi = 2 \cos^{-1} \left ( \cos \frac{\Phi_2}{2} \cos \frac{\Phi_0}{2} + \sin \frac{\Phi_2}{2} \sin \frac {\Phi_0}{2} \ \hat{\boldsymbol{e}}_2 \cdot \hat{\boldsymbol{e}}_0 \right ) + +.. math:: + \hat{\boldsymbol{e}}_3 = \frac{\cos \frac{\Phi_0}{2} \sin \frac{\Phi_2}{2} \ \hat{\boldsymbol{e}}_2 - \cos \frac{\Phi_2}{2} \sin \frac{\Phi_0}{2} \ \hat{\boldsymbol{e}}_0 + \sin \frac{\Phi_2}{2} \sin \frac{\Phi_0}{2} \ \hat{\boldsymbol{e}}_2 \times \hat{\boldsymbol{e}}_0 }{\sin \frac{\Delta \Phi}{2}} + +Note that the initial PRV angle, :math:`\Phi_0` is reset to zero for consecutive rotations so that the +reference PRV angle, :math:`\Phi_{\text{ref}}` is always taken as the full angle to be swept during the rotation. + +During the first half of the rotation, the spinning body is constantly accelerated with the given maximum +angular acceleration. The spinning body's angular velocity increases linearly during the acceleration phase and reaches +a maximum magnitude halfway through the rotation. The switch time, :math:`t_s` is the simulation time halfway +through the rotation: + +.. math:: + t_s = t_0 + \frac{\Delta t}{2} + +where the time required for the rotation, :math:`\Delta t` is determined using the found PRV angle for the rotation: + +.. math:: + \Delta t = t_f - t_0 = 2\sqrt{ \Phi_{\text{ref}} / \alpha_{\text{max}}} + +The resulting trajectory of the angle :math:`\Phi` swept during the first half of the rotation is quadratic. The +profiled motion is concave upwards if the reference angle, :math:`\Phi_{\text{ref}}` is greater than zero. If the +reference angle is negative, the profiled motion is instead concave downwards. The described motion during the first +half of the rotation is characterized by the expressions: + +.. math:: + \ddot{\Phi}(t) = \alpha_{\text{max}} + +.. math:: + \dot{\Phi}(t) = \alpha_{\text{max}} (t - t_0) + \dot{\Phi}(t_0) + +.. math:: + \Phi(t) = a (t - t_0)^2 + +where + +.. math:: + a = \frac{ \frac{1}{2} \Phi_{\text{ref}}}{(t_s - t_0)^2} + +Similarly, the second half of the rotation decelerates the spinning body constantly until it reaches a +non-rotating state. The spinning body's angular velocity decreases linearly from its maximum magnitude back to zero. +The trajectory swept during the second half of the rotation is quadratic and concave downwards if the reference angle, +:math:`\Phi_{\text{ref}}` is greater than zero. If the reference angle is negative, the profiled motion is instead +concave upwards. The described motion during the second half of the rotation is characterized by the +expressions: + +.. math:: + \ddot{\Phi}(t) = -\alpha_{\text{max}} + +.. math:: + \dot{\Phi}(t) = \alpha_{\text{max}} (t - t_f) + +.. math:: + \Phi(t) = b (t - t_f)^2 + \Phi_{\text{ref}} + +where + +.. math:: + b = \frac{ \frac{1}{2} \Phi_{\text{ref}}}{(t_s - t_f)^2} + + +Module Testing +^^^^^^^^^^^^^^ +The unit test for this module simulates TWO consecutive 2 DOF rotational attitude maneuvers for a secondary rigid body +connected to a rigid spacecraft hub. Two maneuvers are simulated to ensure that the module correctly updates the +required relative PRV attitude when a new attitude reference message is written. The unit test checks that the prescribed +body's MRP attitude converges to both reference attitudes for a series of initial and reference attitudes and +maximum angular accelerations. (``sigma_FM_Final1`` is checked to converge to ``sigma_FM_Ref1``, and +``sigma_FM_Final2`` is checked to converge to ``sigma_FM_Ref2``). Additionally, the prescribed body's final angular +velocity magnitude ``thetaDot_Final`` is checked for convergence to the reference angular velocity magnitude, +``thetaDot_Ref``. + + +User Guide +---------- +The user-configurable inputs to the profiler are the maximum angular acceleration for the rotation, +:math:`\alpha_{\text{max}}`, the spinning body's initial attitude with respect to the mount frame as the Principal +Rotation Vector ``prv_F0M`` :math:`(\Phi_0, \hat{\boldsymbol{e}}_0)`, and two reference Principal Rotation Vectors for +the rotation, ``prv_F1F0`` :math:`(\Phi_{1a}, \hat{\boldsymbol{e}}_{1a})` and ``prv_F2F1`` +:math:`(\Phi_{1b}, \hat{\boldsymbol{e}}_{1b})`. + +This module provides a single output message in the form of :ref:`prescribedRotationMsgPayload`. This prescribed +motion output message can be connected to the :ref:`prescribedMotionStateEffector` dynamics module to directly profile +a state effector's rotational motion. Note that a separate translational profiler module must also be connected to +the prescribed motion dynamics module to fully define the kinematic motion of the prescribed body. + +This section is to outline the steps needed to setup a prescribed 2 DOF rotational module in python using Xmera. + +#. Import the prescribedRot1DOF class: + +.. code-block:: python + + from Xmera.fswAlgorithms import prescribedRot2DOF + +#. Create an instantiation of a prescribed rotational 2 DOF C module and the associated C++ container:: + + PrescribedRot2DOF = prescribedRot2DOF.prescribedRot2DOF() + PrescribedRot2DOF.modelTag = "PrescribedRot2DOF" + +#. Define all of the configuration data associated with the module. For example: + +.. code-block:: python + + rotAxis1_M = np.array([0.0, 1.0, 0.0]) # Rotation axis for the first reference rotation angle, thetaRef1a + rotAxis2_F1 = np.array([0.0, 0.0, 1.0]) # Rotation axis for the second reference rotation angle, thetaRef2a + PrescribedRot2DOF.rotAxis1_M = rotAxis1_M + PrescribedRot2DOF.rotAxis2_F1 = rotAxis2_F1 + PrescribedRot2DOF.phiDDotMax = phiDDotMax + PrescribedRot2DOF.omega_FM_F = np.array([0.0, 0.0, 0.0]) # [rad/s] Angular velocity of frame F relative to frame M in F frame components + PrescribedRot2DOF.omegaPrime_FM_F = np.array([0.0, 0.0, 0.0]) # [rad/s^2] B frame time derivative of omega_FB_F in F frame components + PrescribedRot2DOF.sigma_FM = np.array([0.0, 0.0, 0.0]) # MRP attitude of frame F relative to frame M + +The user is required to set the above configuration data parameters, as they are not initialized in the module. + +#. Make sure to connect the required messages for this module. + +#. Add the module to the task list:: + + unitTestSim.AddModelToTask(unitTaskName, PrescribedRot2DOF) diff --git a/src/fswAlgorithms/effectorInterfaces/prescribedTrans/prescribedTrans.rst b/src/fswAlgorithms/effectorInterfaces/prescribedTrans/prescribedTrans.rst index 7925363dd..26de004aa 100644 --- a/src/fswAlgorithms/effectorInterfaces/prescribedTrans/prescribedTrans.rst +++ b/src/fswAlgorithms/effectorInterfaces/prescribedTrans/prescribedTrans.rst @@ -1,163 +1,167 @@ -Executive Summary ------------------ -This module profiles a :ref:`PrescribedTranslationMsgPayload` message for a specified 1 DOF translation -for a secondary prescribed rigid body connected to a rigid spacecraft hub at a hub-fixed location, :math:`\mathcal{M}`. -The body frame for the prescribed body is designated by the frame :math:`\mathcal{F}`. Accordingly, the prescribed -states for the secondary body are written with respect to the mount frame, :math:`\mathcal{M}`. The prescribed states -profiled in this module are: ``r_FM_M``, ``rPrime_FM_M``, and ``rPrimePrime_FM_M``. - -To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` -dynamics module in order to profile the translational states of the secondary body. A second kinematic profiler -module must also be connected to the prescribed motion dynamics module to profile the rotational states of the -prescribed body. The required translation is determined from the user-specified scalar maximum acceleration -:math:`a_{\text{max}}`, the mount frame axis for the translational motion, the prescribed body's initial position -vector with respect to the mount frame :math:`\boldsymbol{r}_{F/M}(t_0)`, and the reference position vector or the -prescribed body with respect to the mount frame :math:`\boldsymbol{r}_{F/M} (\text{ref})`. - -The maximum scalar acceleration is applied constant and positively for the first half of the translation and -constant negatively for the second half of the translation. The resulting velocity of the prescribed body is -linear, approaching a maximum magnitude halfway through the translation and ending with zero residual velocity. -The corresponding translational trajectory the prescribed body moves through during the translation is parabolic in time. - -.. warning:: - This module is now deprecated. See the :ref:`PrescribedLinearTranslation` module that replaces this module. - -Message Connection Descriptions -------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description -provides information on what this message is used for. - -.. list-table:: Module I/O Messages - :widths: 25 25 50 - :header-rows: 1 - - * - Msg Variable Name - - Msg Type - - Description - * - linearTranslationRigidBodyInMsg - - :ref:`LinearTranslationRigidBodyMsgPayload` - - input msg with the prescribed body reference states - * - prescribedTranslationOutMsg - - :ref:`PrescribedTranslationMsgPayload` - - output message with the prescribed body translational states - - -Detailed Module Description ---------------------------- -This translational motion kinematic profiler module is written to profile a rigid body's translational motion with -respect to a hub-fixed mount frame. The inputs to the profiler are the scalar maximum acceleration for the translation -:math:`a_{\text{max}}`, the mount frame axis for the translational motion, the prescribed body's initial position -vector with respect to the mount frame :math:`\boldsymbol{r}_{F/M}(t_0)`, and the reference position vector or the -prescribed body with respect to the mount frame :math:`\boldsymbol{r}_{F/M} (\text{ref})`. -The magnitudes of the initial and final position vectors are denoted :math:`r_0` and :math:`r_{\text{ref}}`, -respectively. The prescribed body is assumed to be at rest at the beginning of the translation. - -Subtracting the initial position from the reference position vector gives the required relative position vector in the -direction of translation: - -.. math:: - \Delta \boldsymbol{r} = \boldsymbol{r}_{F/M}(\text{ref}) - \boldsymbol{r}_{F/M}(t_0) - -The magnitude of the determined relative position vector gives the required translational distance :math:`\Delta r`. -During the first half of the translation, the prescribed body is constantly accelerated with the given maximum -acceleration. The prescribed body's velocity increases linearly during the acceleration phase and reaches a maximum -magnitude halfway through the translation. - -The switch time, :math:`t_s` is the simulation time halfway through the translation: - -.. math:: - t_s = t_0 + \frac{\Delta t}{2} - -The time required for the translation :math:`\Delta t` is determined using the inputs to the profiler: - -.. math:: - \Delta t = \sqrt{\frac{4 r_{\text{ref}} - 8 r_0}{\ddot{a}_{\text{max}}}} - -The resulting trajectory of the position vector :math:`r = || \boldsymbol{r}_{F/M} ||_2` magnitude during the first -half of the translation is parabolic. The profiled motion is concave upwards if the reference position magnitude -:math:`r_{\text{ref}}` is greater than the initial position magnitude :math:`r_0`. If the converse is true, -the profiled motion is instead concave downwards. The described motion during the first half of the translation -is characterized by the expressions: - -.. math:: - r^{''}_{F / M}(t) = a_{\text{max}} - -.. math:: - r^{'}_{F / M}(t) = a_{\text{max}} (t - t_0) - -.. math:: - r_{F / M}(t) = c_1 (t - t_0)^2 + r_0 - -where - -.. math:: - c_1 = \frac{r_{\text{ref}} - r_0}{2(t_s - t_0)^2} - - -Similarly, the second half of the translation decelerates the prescribed body constantly until it reaches the desired -position with zero velocity. The prescribed body velocity decreases linearly from its maximum magnitude back to zero. -The trajectory during the second half of the translation is quadratic and concave downwards if the reference position -magnitude is greater than the initial position magnitude. If the converse is true, the profiled motion is instead -concave upwards. The described motion during the second half of the translation is characterized by the expressions: - -.. math:: - r^{''}_{F / M}(t) = -a_{\text{max}} - -.. math:: - r^{'}_{F / M}(t) = a_{\text{max}} (t - t_f) - -.. math:: - r_{F / M}(t) = c_2 (t - t_f)^2 + r_{\text{ref}} - -where - -.. math:: - c_2 = \frac{r_{\text{ref}} - r_0}{2 (t_s - t_f)^2} - -Module Testing -^^^^^^^^^^^^^^ -This unit test for this module ensures that the profiled translation is properly computed for a series of -initial and reference positions and maximum accelerations. The final prescribed position magnitude ``r_FM_M_Final`` and -velocity magnitude ``rPrime_FM_M_Final`` are compared with the reference values ``r_FM_M_Ref`` and -``rPrime_FM_M_Ref``, respectively. - -User Guide ----------- -The user-configurable inputs to the profiler are the scalar maximum acceleration for the translation -:math:`a_{\text{max}}`, the mount frame axis for the translational motion, the prescribed body's initial position -vector with respect to the mount frame :math:`\boldsymbol{r}_{F/M}(t_0)`, and the reference position vector of the -prescribed body with respect to the mount frame :math:`\boldsymbol{r}_{F/M} (\text{ref})`. - -This module provides a :ref:`PrescribedTranslationMsgPayload` output message that can be connected to the -:ref:`PrescribedMotionStateEffector` dynamics module to directly profile a state effector's translational motion. -Note that a separate rotational profiler module can be connected to the prescribed motion dynamics module -to fully define the kinematic motion of the prescribed body. - -This section is to outline the steps needed to setup a prescribed translational module in python using Xmera. - -#. Import the prescribedTrans class:: - - from Xmera.fswAlgorithms import prescribedTrans - -#. Create an instantiation of a prescribed translational C module and the associated C++ container:: - - PrescribedTrans = prescribedTrans.prescribedTrans() - PrescribedTrans.modelTag = "prescribedTrans" - -#. Define all of the configuration data associated with the module. For example:: - - PrescribedTrans.transAxis_M = np.array([1.0, 0.0, 0.0]) - PrescribedTrans.scalarAccelMax = 0.01 # [m/s^2] - PrescribedTrans.r_FM_M = np.array([0.0, 0.0, 0.0]) - PrescribedTrans.rPrime_FM_M = np.array([0.0, 0.0, 0.0]) - PrescribedTrans.rPrimePrime_FM_M = np.array([0.0, 0.0, 0.0]) - -The user is required to set the above configuration data parameters, as they are not initialized in the module. - -#. Make sure to connect the required messages for this module. - -#. Add the module to the task list:: - - unitTestSim.AddModelToTask(unitTaskName, PrescribedTrans) +Executive Summary +----------------- +This module profiles a :ref:`PrescribedTranslationMsgPayload` message for a specified 1 DOF translation +for a secondary prescribed rigid body connected to a rigid spacecraft hub at a hub-fixed location, :math:`\mathcal{M}`. +The body frame for the prescribed body is designated by the frame :math:`\mathcal{F}`. Accordingly, the prescribed +states for the secondary body are written with respect to the mount frame, :math:`\mathcal{M}`. The prescribed states +profiled in this module are: ``r_FM_M``, ``rPrime_FM_M``, and ``rPrimePrime_FM_M``. + +To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` +dynamics module in order to profile the translational states of the secondary body. A second kinematic profiler +module must also be connected to the prescribed motion dynamics module to profile the rotational states of the +prescribed body. The required translation is determined from the user-specified scalar maximum acceleration +:math:`a_{\text{max}}`, the mount frame axis for the translational motion, the prescribed body's initial position +vector with respect to the mount frame :math:`\boldsymbol{r}_{F/M}(t_0)`, and the reference position vector or the +prescribed body with respect to the mount frame :math:`\boldsymbol{r}_{F/M} (\text{ref})`. + +The maximum scalar acceleration is applied constant and positively for the first half of the translation and +constant negatively for the second half of the translation. The resulting velocity of the prescribed body is +linear, approaching a maximum magnitude halfway through the translation and ending with zero residual velocity. +The corresponding translational trajectory the prescribed body moves through during the translation is parabolic in time. + +.. warning:: + This module is now deprecated. See the :ref:`PrescribedLinearTranslation` module that replaces this module. + +Message Connection Descriptions +------------------------------- +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description +provides information on what this message is used for. + +.. list-table:: Module I/O Messages + :widths: 25 25 50 + :header-rows: 1 + + * - Msg Variable Name + - Msg Type + - Description + * - linearTranslationRigidBodyInMsg + - :ref:`LinearTranslationRigidBodyMsgPayload` + - input msg with the prescribed body reference states + * - prescribedTranslationOutMsg + - :ref:`PrescribedTranslationMsgPayload` + - output message with the prescribed body translational states + + +Detailed Module Description +--------------------------- +This translational motion kinematic profiler module is written to profile a rigid body's translational motion with +respect to a hub-fixed mount frame. The inputs to the profiler are the scalar maximum acceleration for the translation +:math:`a_{\text{max}}`, the mount frame axis for the translational motion, the prescribed body's initial position +vector with respect to the mount frame :math:`\boldsymbol{r}_{F/M}(t_0)`, and the reference position vector or the +prescribed body with respect to the mount frame :math:`\boldsymbol{r}_{F/M} (\text{ref})`. +The magnitudes of the initial and final position vectors are denoted :math:`r_0` and :math:`r_{\text{ref}}`, +respectively. The prescribed body is assumed to be at rest at the beginning of the translation. + +Subtracting the initial position from the reference position vector gives the required relative position vector in the +direction of translation: + +.. math:: + \Delta \boldsymbol{r} = \boldsymbol{r}_{F/M}(\text{ref}) - \boldsymbol{r}_{F/M}(t_0) + +The magnitude of the determined relative position vector gives the required translational distance :math:`\Delta r`. +During the first half of the translation, the prescribed body is constantly accelerated with the given maximum +acceleration. The prescribed body's velocity increases linearly during the acceleration phase and reaches a maximum +magnitude halfway through the translation. + +The switch time, :math:`t_s` is the simulation time halfway through the translation: + +.. math:: + t_s = t_0 + \frac{\Delta t}{2} + +The time required for the translation :math:`\Delta t` is determined using the inputs to the profiler: + +.. math:: + \Delta t = \sqrt{\frac{4 r_{\text{ref}} - 8 r_0}{\ddot{a}_{\text{max}}}} + +The resulting trajectory of the position vector :math:`r = || \boldsymbol{r}_{F/M} ||_2` magnitude during the first +half of the translation is parabolic. The profiled motion is concave upwards if the reference position magnitude +:math:`r_{\text{ref}}` is greater than the initial position magnitude :math:`r_0`. If the converse is true, +the profiled motion is instead concave downwards. The described motion during the first half of the translation +is characterized by the expressions: + +.. math:: + r^{''}_{F / M}(t) = a_{\text{max}} + +.. math:: + r^{'}_{F / M}(t) = a_{\text{max}} (t - t_0) + +.. math:: + r_{F / M}(t) = c_1 (t - t_0)^2 + r_0 + +where + +.. math:: + c_1 = \frac{r_{\text{ref}} - r_0}{2(t_s - t_0)^2} + + +Similarly, the second half of the translation decelerates the prescribed body constantly until it reaches the desired +position with zero velocity. The prescribed body velocity decreases linearly from its maximum magnitude back to zero. +The trajectory during the second half of the translation is quadratic and concave downwards if the reference position +magnitude is greater than the initial position magnitude. If the converse is true, the profiled motion is instead +concave upwards. The described motion during the second half of the translation is characterized by the expressions: + +.. math:: + r^{''}_{F / M}(t) = -a_{\text{max}} + +.. math:: + r^{'}_{F / M}(t) = a_{\text{max}} (t - t_f) + +.. math:: + r_{F / M}(t) = c_2 (t - t_f)^2 + r_{\text{ref}} + +where + +.. math:: + c_2 = \frac{r_{\text{ref}} - r_0}{2 (t_s - t_f)^2} + +Module Testing +^^^^^^^^^^^^^^ +This unit test for this module ensures that the profiled translation is properly computed for a series of +initial and reference positions and maximum accelerations. The final prescribed position magnitude ``r_FM_M_Final`` and +velocity magnitude ``rPrime_FM_M_Final`` are compared with the reference values ``r_FM_M_Ref`` and +``rPrime_FM_M_Ref``, respectively. + +User Guide +---------- +The user-configurable inputs to the profiler are the scalar maximum acceleration for the translation +:math:`a_{\text{max}}`, the mount frame axis for the translational motion, the prescribed body's initial position +vector with respect to the mount frame :math:`\boldsymbol{r}_{F/M}(t_0)`, and the reference position vector of the +prescribed body with respect to the mount frame :math:`\boldsymbol{r}_{F/M} (\text{ref})`. + +This module provides a :ref:`PrescribedTranslationMsgPayload` output message that can be connected to the +:ref:`PrescribedMotionStateEffector` dynamics module to directly profile a state effector's translational motion. +Note that a separate rotational profiler module can be connected to the prescribed motion dynamics module +to fully define the kinematic motion of the prescribed body. + +This section is to outline the steps needed to setup a prescribed translational module in python using Xmera. + +#. Import the prescribedTrans class: + +.. code-block:: python + + from Xmera.fswAlgorithms import prescribedTrans + +#. Create an instantiation of a prescribed translational C module and the associated C++ container:: + + PrescribedTrans = prescribedTrans.prescribedTrans() + PrescribedTrans.modelTag = "prescribedTrans" + +#. Define all of the configuration data associated with the module. For example: + +.. code-block:: python + + PrescribedTrans.transAxis_M = np.array([1.0, 0.0, 0.0]) + PrescribedTrans.scalarAccelMax = 0.01 # [m/s^2] + PrescribedTrans.r_FM_M = np.array([0.0, 0.0, 0.0]) + PrescribedTrans.rPrime_FM_M = np.array([0.0, 0.0, 0.0]) + PrescribedTrans.rPrimePrime_FM_M = np.array([0.0, 0.0, 0.0]) + +The user is required to set the above configuration data parameters, as they are not initialized in the module. + +#. Make sure to connect the required messages for this module. + +#. Add the module to the task list:: + + unitTestSim.AddModelToTask(unitTaskName, PrescribedTrans) diff --git a/src/fswAlgorithms/effectorInterfaces/rwMotorVoltage/rwMotorVoltage.rst b/src/fswAlgorithms/effectorInterfaces/rwMotorVoltage/rwMotorVoltage.rst index 9769b9394..f6f376036 100644 --- a/src/fswAlgorithms/effectorInterfaces/rwMotorVoltage/rwMotorVoltage.rst +++ b/src/fswAlgorithms/effectorInterfaces/rwMotorVoltage/rwMotorVoltage.rst @@ -132,7 +132,9 @@ This code makes the following assumptions: User Guide ========== -The module is configured by:: +The module is configured by: + +.. code-block:: python module = rwMotorVoltage.RwMotorVoltage(minVoltageMagnitude, maxVoltageMagnitude) module.modelTag = "rwMotorVoltage" diff --git a/src/fswAlgorithms/imageProcessing/regionsOfInterest/regionsOfInterest.rst b/src/fswAlgorithms/imageProcessing/regionsOfInterest/regionsOfInterest.rst index dd4614ff2..971f231c1 100644 --- a/src/fswAlgorithms/imageProcessing/regionsOfInterest/regionsOfInterest.rst +++ b/src/fswAlgorithms/imageProcessing/regionsOfInterest/regionsOfInterest.rst @@ -215,7 +215,9 @@ User Guide This section provides implementation guidance for integrating the Regions of Interest module into a flight software simulation. The following steps demonstrate the standard configuration workflow in Python. -#. Import the regionsOfInterest class:: +#. Import the regionsOfInterest class: + +.. code-block:: python from Basilisk.fswAlgorithms import regionsOfInterest @@ -225,14 +227,18 @@ software simulation. The following steps demonstrate the standard configuration roiModule.ModelTag = "roiModule" #. Configure the maximum separation distance for region merging. This parameter defines the spatial threshold - for determining whether multiple detected regions should be merged into a single composite target:: + for determining whether multiple detected regions should be merged into a single composite target: + +.. code-block:: python roiModule.setMaxRoiSeparation(100) # pixels Regions with centers of brightness separated by less than this distance from the barycenter may be merged, depending on the proximity analysis outcome. -#. (Optional) Configure spatial windowing to constrain the search region:: +#. (Optional) Configure spatial windowing to constrain the search region: + +.. code-block:: python import numpy as np windowCenter = np.array([512, 384], dtype=int) # pixels @@ -277,7 +283,9 @@ For multi-camera systems, assign a unique camera identifier to facilitate downst **Minimum Detection Threshold:** Configure the minimum pixel count threshold for valid region detection. Regions below this threshold are -excluded as noise or spurious detections:: +excluded as noise or spurious detections: + +.. code-block:: python roiModule.setMinimumDetectionSize(10) # pixels diff --git a/src/fswAlgorithms/opticalNavigation/cobConverter/cobConverter.rst b/src/fswAlgorithms/opticalNavigation/cobConverter/cobConverter.rst index d8c411126..15cb03a77 100644 --- a/src/fswAlgorithms/opticalNavigation/cobConverter/cobConverter.rst +++ b/src/fswAlgorithms/opticalNavigation/cobConverter/cobConverter.rst @@ -222,11 +222,15 @@ User Guide ---------- This section is to outline the steps needed to setup a center of brightness converter in Python. -#. Import the module:: +#. Import the module: + +.. code-block:: python from Xmera.fswAlgorithms import cobConverter -#. Create an instantiation of converter class. The COM/COB correction method and object radius need to be specified:: +#. Create an instantiation of converter class. The COM/COB correction method and object radius need to be specified: + +.. code-block:: python module = cobConverter.CobConverter(cobConverter.PhaseAngleCorrectionMethod_NoCorrection, R_obj) # no correction # module = cobConverter.CobConverter(cobConverter.PhaseAngleCorrectionMethod_Lambertian, R_obj) # Lambertian method @@ -244,7 +248,9 @@ This section is to outline the steps needed to setup a center of brightness conv module.enableOutlierDetection() -#. The number of acceptable standard deviations and the standard deviation itself for COB outlier detection are set by:: +#. The number of acceptable standard deviations and the standard deviation itself for COB outlier detection are set by: + +.. code-block:: python module.setNumStandardDeviations(3) # default 3 module.setStandardDeviation(100) # if not set, then the standard deviation is dynamically updated by the module diff --git a/src/fswAlgorithms/opticalNavigation/flybyODuKF/flybyODuKF.rst b/src/fswAlgorithms/opticalNavigation/flybyODuKF/flybyODuKF.rst index a3598d409..3aa96b067 100644 --- a/src/fswAlgorithms/opticalNavigation/flybyODuKF/flybyODuKF.rst +++ b/src/fswAlgorithms/opticalNavigation/flybyODuKF/flybyODuKF.rst @@ -28,7 +28,7 @@ provides information on what this message is used for. - :ref:`FilterMsgPayload` - output filter data message containing states and covariances * - opNavResidualMsg - - :ref:`FilterResidualMsgPayload` + - :ref:`FilterResidualsMsgPayload` - output measurement data message containing residuals * - opNavHeadingMsg - :ref:`OpNavUnitVecMsgPayload` diff --git a/src/fswAlgorithms/opticalNavigation/linearODeKF/linearODeKF.rst b/src/fswAlgorithms/opticalNavigation/linearODeKF/linearODeKF.rst index 28f8d457a..8a6a7b095 100644 --- a/src/fswAlgorithms/opticalNavigation/linearODeKF/linearODeKF.rst +++ b/src/fswAlgorithms/opticalNavigation/linearODeKF/linearODeKF.rst @@ -28,7 +28,7 @@ provides information on what this message is used for. - :ref:`FilterMsgPayload` - output filter data message containing states and covariances * - opNavResidualMsg - - :ref:`FilterResidualMsgPayload` + - :ref:`FilterResidualsMsgPayload` - output measurement data message containing residuals * - opNavHeadingMsg - :ref:`OpNavUnitVecMsgPayload` diff --git a/src/fswAlgorithms/opticalNavigation/positionODuKF/positionODuKF.rst b/src/fswAlgorithms/opticalNavigation/positionODuKF/positionODuKF.rst index f091b70ee..8600e5577 100644 --- a/src/fswAlgorithms/opticalNavigation/positionODuKF/positionODuKF.rst +++ b/src/fswAlgorithms/opticalNavigation/positionODuKF/positionODuKF.rst @@ -30,10 +30,10 @@ provides information on what this message is used for. - :ref:`FilterMsgPayload` - output filter data message containing states and covariances * - opNavResidualMsg - - :ref:`FilterResidualMsgPayload` + - :ref:`FilterResidualsMsgPayload` - output measurement data message containing residuals * - cameraPosMsg - - :ref:`CameraLocalizationMsgPayload.h` + - :ref:`CameraLocalizationMsgPayload` - opnav input message containing the position vector towards the target Module models @@ -72,7 +72,9 @@ User Guide ---------- This section is to outline the steps needed to setup a positionODSRuKF converter in Python. -#. Import the module:: +#. Import the module: + +.. code-block:: python from Xmera.fswAlgorithms import positionODSRuKF @@ -85,7 +87,9 @@ This section is to outline the steps needed to setup a positionODSRuKF converter positionOD.alpha = 0.02 positionOD.beta = 2.0 -#. Setup SRuKF measurement parameters, measurement noise Standard Deviation is given in meters:: +#. Setup SRuKF measurement parameters, measurement noise Standard Deviation is given in meters: + +.. code-block:: python positionOD.muCentral = 3000*1E9 positionOD.measNoiseScaling = 1 diff --git a/src/moduleTemplates/_doc.rst b/src/moduleTemplates/_doc.rst index 5f0b6e4bd..b6dde6d4a 100644 --- a/src/moduleTemplates/_doc.rst +++ b/src/moduleTemplates/_doc.rst @@ -3,11 +3,11 @@ General Purpose --------------- The purpose of this folder is to provide examples of Xmera module templates. It contains a fully functioning -sample C++ module, as well as two modules which are auto-generated using the :ref:`makeDraftModule` +sample C++ module, as well as two modules which are auto-generated using the ``makeDraftModule`` script found in ``src/utilities/makeDraftModule.py``. A module folder can contain a series of related module folders. By adding a ``*.rst`` file to this folder the purpose of a folder can be documented. The ``*.rst`` file name should be the same as the parent folder. -Note that the :ref:`cModuleTemplate` has an expanded module documentation file that discusses in detail +Note that the ``cModuleTemplate`` has an expanded module documentation file that discusses in detail what can be included, and how RST can be used to include math, figures, citations, links, tables, etc. The sub-folder called ``_GeneralModuleFiles`` contains support ``*.c/h`` files that are used by all modules. As a minimum, a file is required that defines the Module specific output message type @@ -53,7 +53,7 @@ To use the template module: Usage of ``makeDraftModules.py`` -------------------------------- -The script :ref:`makeDraftModule` in ``xmera/src/utilities/makeDraftModule.py`` +The script ``makeDraftModule`` in ``xmera/src/utilities/makeDraftModule.py`` provides a class that creates a default Xmera module folder and associated ``.c/cpp``, ``.h``, ``.i``, ``.rst`` and ``_UnitTest/test_xxx.py`` files. When running ``python3 conanfile.py`` this script is used to create the ``autoCModule`` and ``autoCppModule`` folders. diff --git a/src/moduleTemplates/cppModuleTemplate/cppModuleTemplate.rst b/src/moduleTemplates/cppModuleTemplate/cppModuleTemplate.rst index 347483f59..fb8380449 100644 --- a/src/moduleTemplates/cppModuleTemplate/cppModuleTemplate.rst +++ b/src/moduleTemplates/cppModuleTemplate/cppModuleTemplate.rst @@ -2,7 +2,7 @@ Executive Summary ----------------- This is a very basic dummy C++ Xmera module that can be used as a template to create other C++ modules. -It mimics the functionality of :ref:`cModuleTemplate`. See that module for a more complete discussion +It mimics the functionality of ``cModuleTemplate``. See that module for a more complete discussion of how to write the RST module documentation file. @@ -20,9 +20,9 @@ provides information on what this message is used for. - Msg Type - Description * - dataInMsg - - :ref:`CModuleTemplateMsgPayload` + - ``CModuleTemplateMsgPayload`` - (optional) Input message description. Note here if this message is optional, and what the default behavior is if this message is not provided. * - dataOutMsg - - :ref:`CModuleTemplateMsgPayload` + - ``CModuleTemplateMsgPayload`` - Output message description. diff --git a/src/simulation/deviceInterface/prescribedLinearTranslation/prescribedLinearTranslation.rst b/src/simulation/deviceInterface/prescribedLinearTranslation/prescribedLinearTranslation.rst index 7b593f464..0207bce46 100644 --- a/src/simulation/deviceInterface/prescribedLinearTranslation/prescribedLinearTranslation.rst +++ b/src/simulation/deviceInterface/prescribedLinearTranslation/prescribedLinearTranslation.rst @@ -1,473 +1,479 @@ -Executive Summary ------------------ -This module profiles linear translational motion for a rigid body connected to a rigid spacecraft hub. The body frame of -the translating body is designated by the frame :math:`\mathcal{F}`. The states of the translating body are profiled -relative to a hub-fixed frame :math:`\mathcal{M}`. The :ref:`PrescribedTranslationMsgPayload` message is used to output -the prescribed translational states from the module. The prescribed states profiled in this module are: ``r_FM_M``, -``rPrime_FM_M``, and ``rPrimePrime_FM_M``. This module has four options to profile the linear translation. -The first option is a bang-bang acceleration profile that minimizes the time required to complete the translation. -The second option is a bang-coast-bang acceleration profile that adds a coast period of zero acceleration between the -acceleration ramp segments. The third option is a smoothed bang-bang acceleration profile that uses cubic splines to -construct a continuous acceleration profile across the entire translation. The fourth option is a smoothed -bang-coast-bang acceleration profile. - -The module defaults to the non-smoothed bang-bang option with no coast period. If the coast option is desired, the -user must set the module variable ``coastOptionBangDuration`` to a nonzero value. If smoothing is desired, -the module variable ``smoothingDuration`` must be set to a nonzero value. - -.. important:: - Note that this module assumes the initial and final hub-relative translational rates of the translating body are zero. - -The general inputs to this module that must be set by the user are the translational axis expressed as a -unit vector in mount frame components ``transHat_M``, the initial translational body position relative to the hub-fixed -mount frame ``transPosInit``, the reference position relative to the mount frame ``transPosRef``, and the maximum scalar -linear acceleration for the translation ``transAccelMax``. The optional inputs ``coastOptionBangDuration`` and -``smoothingDuration`` can be set by the user to select the specific type of profiler that is desired. If these variables -are not set by the user, the module defaults to the non-smoothed bang-bang profiler. If only the variable -``coastOptionBangDuration`` is set to a nonzero value, the bang-coast-bang profiler is selected. If only the variable -``smoothingDuration`` is set to a nonzero value, the smoothed bang-bang profiler is selected. If both variables are -set to nonzero values, the smoothed bang-coast-bang profiler is selected. - -.. important:: - To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` - dynamics module. This ensures the translational body's states are correctly incorporated into the spacecraft - dynamics. - - -Message Connection Descriptions -------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description -provides information on what this message is used for. - -.. list-table:: Module I/O Messages - :widths: 25 25 50 - :header-rows: 1 - - * - Msg Variable Name - - Msg Type - - Description - * - linearTranslationRigidBodyInMsg - - :ref:`LinearTranslationRigidBodyMsgPayload` - - input msg with the prescribed body reference translational states - * - prescribedTranslationOutMsg - - :ref:`PrescribedTranslationMsgPayload` - - output message with the prescribed body translational states - * - prescribedTranslationOutMsgC - - :ref:`PrescribedTranslationMsgPayload` - - C-wrapped output message with the prescribed body translational states - -Detailed Module Description ---------------------------- - -Non-Smoothed Bang-Bang Profiler -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The first option to profile the linear translation is a pure bang-bang acceleration profile. If the given reference -position is greater than the given initial position, the user-specified maximum acceleration value -is applied positively to the first half of the translation and negatively to the second half of the translation. -However, if the reference position is less than the initial position, the acceleration is instead applied -negatively during the first half of the translation and positively during the second half of the translation. As a -result of this acceleration profile, the translational body's hub-relative velocity changes linearly with time and -reaches a maximum in magnitude halfway through the translation. Note that the velocity is assumed to both start and -end at zero in this module. The resulting translational position profile is parabolic in time. - -To profile this motion, the translational body's hub-relative scalar states :math:`\rho`, :math:`\dot{\rho}`, and -:math:`\ddot{\rho}` are prescribed as a function of time. During the first half of the translation the states are: - -.. math:: - \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} - -.. math:: - \dot{\rho}(t) = \ddot{\rho} (t - t_0) + \dot{\rho}_0 - -.. math:: - \rho(t) = a (t - t_0)^2 + \rho_0 - -where - -.. math:: - a = \frac{ \rho_{\text{ref}} - \rho_0}{2 (t_{b1} - t_0)^2} - -During the second half of the translation the states are: - -.. math:: - \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} - -.. math:: - \dot{\rho}(t) = \ddot{\rho} (t - t_f) + \dot{\rho}_0 - -.. math:: - \rho(t) = b (t - t_f)^2 + \rho_{\text{ref}} - -where - -.. math:: - b = - \frac{ \rho_{\text{ref}} - \rho_0}{2 (t_{b1} - t_f)^2} - -The switch time :math:`t_{b1}` is the simulation time at the end of the first bang segment: - -.. math:: - t_{b1} = t_0 + \frac{\Delta t_{\text{tot}}}{2} - -The total time required to complete the translation :math:`\Delta t_{\text{tot}}` is: - -.. math:: - \Delta t_{\text{tot}} = 2 \sqrt{ \frac{| \rho_{\text{ref}} - \rho_0 | }{\ddot{\rho}_{\text{max}}}} = t_f - t_0 - -Non-Smoothed Bang-Coast-Bang Profiler -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The second option to profile the linear translation is a bang-coast-bang acceleration profile with an added coast -period between the acceleration segments where the acceleration is zero. Similar to the previous profiler, if the -reference position is greater than the given initial position, the maximum acceleration value is applied -positively for the specified ramp time ``coastOptionBangDuration`` to the first segment of the translation and negatively -to the third segment of the translation. The second segment of the translation is the coast period. However, if the -reference position is less than the initial position, the acceleration is instead applied negatively during the first -segment of the translation and positively during the third segment of the translation. As a result of this acceleration -profile, the translational body's hub-relative velocity changes linearly with time and reaches a maximum in magnitude -at the end of the first segment and is constant during the coast segment. The velocity returns to zero during the -third segment. The resulting position profiled is parabolic during the first and third segments and linear during the -coast segment. - -To profile this linear motion, the scalar translating body's hub-relative states :math:`\rho`, :math:`\dot{\rho}`, and -:math:`\ddot{\rho}` are prescribed as a function of time. During the first segment of the translation the states are: - -.. math:: - \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} - -.. math:: - \dot{\rho}(t) = \ddot{\rho} (t - t_0) + \dot{\rho}_0 - -.. math:: - \rho(t) = a (t - t_0)^2 + \rho_0 - -where - -.. math:: - a = \frac{ \rho(t_{b1}) - \rho_0}{2 (t_{b1} - t_0)^2} - -and :math:`\rho(t_{b1})` is the hub-relative position at the end of the first bang segment: - -.. math:: - \rho(t_{b1}) = \pm \frac{1}{2} \ddot{\rho}_{\text{max}} t_{\text{bang}}^2 + \dot{\rho}_0 t_{\text{bang}} + \rho_0 - -.. important:: - Note the distinction between :math:`t_{b1}` and :math:`t_{\text{bang}}`. :math:`t_{\text{bang}}` is the time - duration of the acceleration segment and :math:`t_{b1}` is the simulation time at the end of the first acceleration - segment. :math:`t_{b1} = t_0 + t_{\text{bang}}` - -During the coast segment, the translational states are: - -.. math:: - \ddot{\rho}(t) = 0 - -.. math:: - \dot{\rho}(t) = \dot{\rho}(t_{b1}) = \ddot{\rho}_{\text{max}} t_{\text{bang}} + \dot{\rho}_0 - -.. math:: - \rho(t) = \dot{\rho}(t_{b1}) (t - t_{b1}) + \rho(t_{b1}) - -During the third segment, the translational states are - -.. math:: - \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} - -.. math:: - \dot{\rho}(t) = \ddot{\rho} (t - t_f) + \dot{\rho}_0 - -.. math:: - \rho(t) = b (t - t_f)^2 + \rho_{\text{ref}} - -where - -.. math:: - b = - \frac{ \rho_{\text{ref}} - \rho(t_c) }{(t_c - t_f)^2} - -Here :math:`\rho(t_c)` is the hub-relative position at the end of the coast segment: - -.. math:: - \rho(t_c) = \rho(t_{b1}) + \Delta \rho_{\text{coast}} - -and :math:`\Delta \rho_{\text{coast}}` is the distance traveled during the coast segment: - -.. math:: - \Delta \rho_{\text{coast}} = (\rho_{\text{ref}} - \rho_0) - 2 (\rho(t_{b1}) - \rho_0) - -:math:`t_c` is the simulation time at the end of the coast segment: - -.. math:: - t_c = t_{b1} + \frac{\Delta \rho_{\text{coast}}}{\dot{\rho}(t_{b1})} - -Using the given translation axis ``transHat_M``, the scalar states are then transformed to the prescribed translational -states ``r_FM_M``, ``rPrime_FM_M``, and ``rPrimePrime_FM_M``. The states are then written to the -:ref:`PrescribedTranslationMsgPayload` module output message. - -Smoothed Bang-Bang Profiler -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The third option to profile the linear translation is a smoothed bang-bang acceleration profile. This option is selected -by setting the module variable ``smoothingDuration`` to a nonzero value. This profiler uses cubic splines to construct -a continuous acceleration profiler across the entire translation. Similar to the non-smoothed bang-bang profiler, -this option smooths the acceleration between the given maximum acceleration values. -To profile this motion, the translational body's hub-relative scalar states :math:`\rho`, :math:`\dot{\rho}`, and -:math:`\ddot{\rho}` are prescribed as a function of time and the translational motion is split into five different -segments. - -The first segment smooths the acceleration from zero to the user-specified maximum acceleration value in the given -time ``smoothingDuration``. If the given reference position is greater than the given initial position, the -acceleration is smoothed positively to the given maximum acceleration value. If the given reference position is less -than the given initial position, the acceleration is smoothed from zero to the negative maximum acceleration value. -During this phase, the scalar hub-relative states are: - -.. math:: - \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{3 (t - t_0)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_0)^3}{t_{\text{smooth}}^3} \right) - -.. math:: - \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_0)^3}{t_{\text{smooth}}^2} - \frac{(t - t_0)^4}{2 t_{\text{smooth}}^3} \right) - -.. math:: - \rho(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_0)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_0)^5}{10 t_{\text{smooth}}^3} \right) - -The second segment is the first bang segment where the maximum acceleration value is applied either positively or -negatively as discussed previously. The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} - -.. math:: - \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} (t - t_{s1}) + \dot{\rho}(t_{s1}) - -.. math:: - \rho(t) = \pm \frac{\ddot{\rho}_{\text{max}} (t - t_{s1})^2}{2} + \dot{\rho}(t_{s1})(t - t_{s1}) + \rho(t_{s1}) - -where :math:`t_{s1}` is the time at the end of the first smoothing segment: - -.. math:: - t_{s1} = t_0 + t_{\text{smooth}} - -The third segment smooths the acceleration from the current maximum acceleration value to the opposite magnitude maximum -acceleration value. The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( 1 - \frac{3 (t - t_{b1})^2}{2 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^3}{2 t_{\text{smooth}}^3} \right) - -.. math:: - \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( (t - t_{b1}) - \frac{(t - t_{b1})^3}{2 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^4}{8 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_{b1}) - -.. math:: - \rho(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_{b1})^2}{2} - \frac{(t - t_{b1})^4}{8 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^5}{40 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_{b1})(t - t_{b1}) + \rho(t_{b1}) - -where :math:`t_{b1}` is the time at the end of the first bang segment: - -.. math:: - t_{b1} = t_{s1} + t_{\text{bang}} - -The fourth segment is the second bang segment where the maximum acceleration value is applied either positively or -negatively as discussed previously. The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} - -.. math:: - \dot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} (t - t_{s2}) + \dot{\rho}(t_{s2}) - -.. math:: - \rho(t) = \mp \frac{\ddot{\rho}_{\text{max}} (t - t_{s2})^2}{2} + \dot{\rho}(t_{s2})(t - t_{s2}) + \rho(t_{s2}) - -where :math:`t_{s2}` is the time at the end of the second smoothing segment: - -.. math:: - t_{s2} = t_{b1} + t_{\text{smooth}} - -The fifth segment is the third and final smoothing segment where the acceleration returns to zero. The scalar -hub-relative states during this phase are: - -.. math:: - \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} \left ( -1 + \frac{3(t - t_{b2})^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_{b2})^3}{t_{\text{smooth}}^3} \right ) - -.. math:: - \dot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} \left ( -(t - t_{b2}) + \frac{(t - t_{b2})^3}{t_{\text{smooth}}^2} - \frac{(t - t_{b2})^4}{2 t_{\text{smooth}}^3} \right ) + \dot{\rho}(t_{b2}) - -.. math:: - \rho(t) = \mp \ddot{\rho}_{\text{max}} \left ( \frac{(t - t_{b2})^2}{2} + \frac{(t - t_{b2})^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_{b2})^5}{10 t_{\text{smooth}}^3} \right ) + \dot{\rho}(t_{b2})(t - t_{b2}) + \rho(t_{b2}) - -where :math:`t_{b2}` is the time at the end of the second bang segment: - -.. math:: - t_{b2} = t_{s2} + t_{\text{bang}} - -Smoothed Bang-Coast-Bang Profiler -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The fourth option to profile the linear translation is a smoothed bang-coast-bang acceleration profile. This option is -selected by setting the module variables ``coastOptionBangDuration`` and ``smoothingDuration`` to nonzero values. -This profiler uses cubic splines to construct a continuous acceleration profiler across the entire translation. -To profile this motion, the translational body's hub-relative scalar states :math:`\rho`, :math:`\dot{\rho}`, and -:math:`\ddot{\rho}` are prescribed as a function of time and the translational motion is split into seven different -segments. - -The first segment smooths the acceleration from zero to the user-specified maximum acceleration value in the given -time ``smoothingDuration``. If the given reference position is greater than the given initial position, the -acceleration is smoothed positively to the given maximum acceleration value. If the given reference position is less -than the given initial position, the acceleration is smoothed from zero to the negative maximum acceleration value. -During this phase, the scalar hub-relative states are: - -.. math:: - \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{3 (t - t_0)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_0)^3}{t_{\text{smooth}}^3} \right) - -.. math:: - \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_0)^3}{t_{\text{smooth}}^2} - \frac{(t - t_0)^4}{2 t_{\text{smooth}}^3} \right) - -.. math:: - \rho(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_0)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_0)^5}{10 t_{\text{smooth}}^3} \right) - -The second segment is the first bang segment where the maximum acceleration value is applied either positively or -negatively as discussed previously. The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} - -.. math:: - \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} (t - t_{s1}) + \dot{\rho}(t_{s1}) - -.. math:: - \rho(t) = \pm \frac{\ddot{\rho}_{\text{max}} (t - t_{s1})^2}{2} + \dot{\rho}(t_{s1})(t - t_{s1}) + \rho(t_{s1}) - -where :math:`t_{s1}` is the time at the end of the first smoothing segment. - -The third segment prior to the coast phase smooths the acceleration from the current maximum acceleration value to zero. -The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( 1 - \frac{3 (t - t_{b1})^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_{b1})^3}{t_{\text{smooth}}^3} \right) - -.. math:: - \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( (t - t_{b1}) - \frac{(t - t_{b1})^3}{t_{\text{smooth}}^2} - \frac{(t - t_{b1})^4}{2 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_{b1}) - -.. math:: - \rho(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_{b1})^2}{2} - \frac{(t - t_{b1})^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_{b1})^5}{10 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_{b1})(t - t_{b1}) + \rho(t_{b1}) - -where :math:`t_{b1}` is the time at the end of the first bang segment. - -The fourth segment is the coast segment where the translational states are: - -.. math:: - \ddot{\rho}(t) = 0 - -.. math:: - \dot{\rho}(t) = \dot{\rho}(t_{s2}) - -.. math:: - \rho(t) = \dot{\rho}(t_{s2}) (t - t_{s2}) + \rho(t_{s2}) - -where :math:`t_{s2}` is the time at the end of the second smoothing segment. - -The fifth segment smooths the acceleration from zero to the maximum acceleration value prior to the second bang segment. -The translational states during this phase are: - -.. math:: - \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} \left( \frac{3 (t - t_c)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_c)^3}{t_{\text{smooth}}^3} \right) - -.. math:: - \dot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} \left( \frac{(t - t_c)^3}{t_{\text{smooth}}^2} - \frac{(t - t_c)^4}{2 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_c) - -.. math:: - \rho(t) = \mp \ddot{\rho}_{\text{max}} \left( \frac{(t - t_c)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_c)^5}{10 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_c) (t - t_c) + \rho(t_c) - -where :math:`t_c` is the time at the end of the coast segment. - -The sixth segment is the second bang segment where the maximum acceleration value is applied either positively or -negatively as discussed previously. The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} - -.. math:: - \dot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} (t - t_{s3}) + \dot{\rho}(t_{s3}) - -.. math:: - \rho(t) = \mp \frac{\ddot{\rho}_{\text{max}} (t - t_{s3})^2}{2} + \dot{\rho}(t_{s3})(t - t_{s3}) + \rho(t_{s3}) - -where :math:`t_{s3}` is the time at the end of the third smoothing segment. - -The seventh segment is the fourth and final smoothing segment where the acceleration returns to zero. The scalar -hub-relative states during this phase are: - -.. math:: - \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} \left (\frac{3(t_f - t)^2}{t_{\text{smooth}}^2} - \frac{2 (t_f - t)^3}{t_{\text{smooth}}^3} \right ) - -.. math:: - \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left (\frac{(t_f - t)^3}{t_{\text{smooth}}^2} - \frac{(t_f - t)^4}{2 t_{\text{smooth}}^3} \right ) - -.. math:: - \rho(t) = \mp \ddot{\rho}_{\text{max}} \left (\frac{(t_f - t)^4}{4 t_{\text{smooth}}^2} - \frac{(t_f - t)^5}{10 t_{\text{smooth}}^3} \right ) + \rho_{\text{ref}} - -where :math:`t_f` is the time at the end of the translation: - -Module Testing -^^^^^^^^^^^^^^ -The unit test for this module ensures that the profiled linear translation for a secondary rigid body relative to -the spacecraft hub is properly computed for several different simulation configurations. The unit test profiles -two successive translations to ensure the module is correctly configured. The secondary body's initial scalar -translational position relative to the spacecraft hub is varied, along with the two final reference positions -and the maximum translational acceleration. - -The unit test also tests four different methods of profiling the translation. Two profilers prescribe a pure -bang-bang or bang-coast-bang linear acceleration profile for the translation. The bang-bang option results in -the fastest possible translation; while the bang-coast-bang option includes a coast period with zero acceleration -between the acceleration segments. The other two profilers apply smoothing to the bang-bang and bang-coast-bang -acceleration profiles so that the secondary body hub-relative rates start and end at zero. - -To verify the module functionality, the final position at the end of each translation segment is checked to match -the specified reference positions. Additionally, for the smoothed profiler options, the numerical derivative of the -profiled displacements and velocities is determined across the entire simulation. These numerical derivatives are -checked with the module's acceleration and velocity profiles to ensure the profiled acceleration is correctly -integrated in the module to obtain the displacements and velocities. - -User Guide ----------- -The general inputs to this module that must be set by the user are the translational axis expressed as a -unit vector in mount frame components ``transHat_M``, the initial translational body position relative to the hub-fixed -mount frame ``transPosInit``, the reference position relative to the mount frame ``transPosRef``, and the maximum scalar -linear acceleration for the translation ``transAccelMax``. The optional inputs ``coastOptionBangDuration`` and -``smoothingDuration`` can be set by the user to select the specific type of profiler that is desired. If these variables -are not set by the user, the module defaults to the non-smoothed bang-bang profiler. If only the variable -``coastOptionBangDuration`` is set to a nonzero value, the bang-coast-bang profiler is selected. If only the variable -``smoothingDuration`` is set to a nonzero value, the smoothed bang-bang profiler is selected. If both variables are -set to nonzero values, the smoothed bang-coast-bang profiler is selected. - -This section is to outline the steps needed to setup the prescribed linear translational module in python using Xmera. - -#. Import the prescribedLinearTranslation class:: - - from Xmera.simulation import prescribedLinearTranslation - -#. Create an instantiation of the module:: - - prescribedLinearTrans = prescribedLinearTranslation.PrescribedLinearTranslation() - -#. Define all of the configuration data associated with the module. For example, to configure the smoothed bang-coast-bang option:: - - prescribedLinearTrans.modelTag = "prescribedLinearTranslation" - prescribedLinearTrans.setTransHat_M(np.array([0.5, 0.0, 0.5 * np.sqrt(3)])) - prescribedLinearTrans.setTransAccelMax(0.01) # [m/s^2] - prescribedLinearTrans.setTransPosInit(0.5) # [m] - prescribedLinearTrans.setCoastRampDuration(1.0) # [s] - prescribedLinearTrans.setSmoothingDuration(1.0) # [s] - -#. Connect a :ref:`LinearTranslationRigidBodyMsgPayload` message for the translating body reference position to the module. For example, the user can create a stand-alone message to specify the reference position:: - - linearTranslationRigidBodyMessageData = messaging.LinearTranslationRigidBodyMsgPayload() - linearTranslationRigidBodyMessageData.rho = 1.0 # [m] - linearTranslationRigidBodyMessageData.rhoDot = 0.0 # [m/s] - linearTranslationRigidBodyMessage = messaging.LinearTranslationRigidBodyMsg().write(linearTranslationRigidBodyMessageData) - -#. Subscribe the reference message to the prescribedTranslation module input message:: - - prescribedLinearTrans.linearTranslationRigidBodyInMsg.subscribeTo(linearTranslationRigidBodyMessage) - -#. Add the module to the task list:: - - unitTestSim.AddModelToTask(unitTaskName, prescribedLinearTrans) +Executive Summary +----------------- +This module profiles linear translational motion for a rigid body connected to a rigid spacecraft hub. The body frame of +the translating body is designated by the frame :math:`\mathcal{F}`. The states of the translating body are profiled +relative to a hub-fixed frame :math:`\mathcal{M}`. The :ref:`PrescribedTranslationMsgPayload` message is used to output +the prescribed translational states from the module. The prescribed states profiled in this module are: ``r_FM_M``, +``rPrime_FM_M``, and ``rPrimePrime_FM_M``. This module has four options to profile the linear translation. +The first option is a bang-bang acceleration profile that minimizes the time required to complete the translation. +The second option is a bang-coast-bang acceleration profile that adds a coast period of zero acceleration between the +acceleration ramp segments. The third option is a smoothed bang-bang acceleration profile that uses cubic splines to +construct a continuous acceleration profile across the entire translation. The fourth option is a smoothed +bang-coast-bang acceleration profile. + +The module defaults to the non-smoothed bang-bang option with no coast period. If the coast option is desired, the +user must set the module variable ``coastOptionBangDuration`` to a nonzero value. If smoothing is desired, +the module variable ``smoothingDuration`` must be set to a nonzero value. + +.. important:: + Note that this module assumes the initial and final hub-relative translational rates of the translating body are zero. + +The general inputs to this module that must be set by the user are the translational axis expressed as a +unit vector in mount frame components ``transHat_M``, the initial translational body position relative to the hub-fixed +mount frame ``transPosInit``, the reference position relative to the mount frame ``transPosRef``, and the maximum scalar +linear acceleration for the translation ``transAccelMax``. The optional inputs ``coastOptionBangDuration`` and +``smoothingDuration`` can be set by the user to select the specific type of profiler that is desired. If these variables +are not set by the user, the module defaults to the non-smoothed bang-bang profiler. If only the variable +``coastOptionBangDuration`` is set to a nonzero value, the bang-coast-bang profiler is selected. If only the variable +``smoothingDuration`` is set to a nonzero value, the smoothed bang-bang profiler is selected. If both variables are +set to nonzero values, the smoothed bang-coast-bang profiler is selected. + +.. important:: + To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` + dynamics module. This ensures the translational body's states are correctly incorporated into the spacecraft + dynamics. + + +Message Connection Descriptions +------------------------------- +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description +provides information on what this message is used for. + +.. list-table:: Module I/O Messages + :widths: 25 25 50 + :header-rows: 1 + + * - Msg Variable Name + - Msg Type + - Description + * - linearTranslationRigidBodyInMsg + - :ref:`LinearTranslationRigidBodyMsgPayload` + - input msg with the prescribed body reference translational states + * - prescribedTranslationOutMsg + - :ref:`PrescribedTranslationMsgPayload` + - output message with the prescribed body translational states + * - prescribedTranslationOutMsgC + - :ref:`PrescribedTranslationMsgPayload` + - C-wrapped output message with the prescribed body translational states + +Detailed Module Description +--------------------------- + +Non-Smoothed Bang-Bang Profiler +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The first option to profile the linear translation is a pure bang-bang acceleration profile. If the given reference +position is greater than the given initial position, the user-specified maximum acceleration value +is applied positively to the first half of the translation and negatively to the second half of the translation. +However, if the reference position is less than the initial position, the acceleration is instead applied +negatively during the first half of the translation and positively during the second half of the translation. As a +result of this acceleration profile, the translational body's hub-relative velocity changes linearly with time and +reaches a maximum in magnitude halfway through the translation. Note that the velocity is assumed to both start and +end at zero in this module. The resulting translational position profile is parabolic in time. + +To profile this motion, the translational body's hub-relative scalar states :math:`\rho`, :math:`\dot{\rho}`, and +:math:`\ddot{\rho}` are prescribed as a function of time. During the first half of the translation the states are: + +.. math:: + \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} + +.. math:: + \dot{\rho}(t) = \ddot{\rho} (t - t_0) + \dot{\rho}_0 + +.. math:: + \rho(t) = a (t - t_0)^2 + \rho_0 + +where + +.. math:: + a = \frac{ \rho_{\text{ref}} - \rho_0}{2 (t_{b1} - t_0)^2} + +During the second half of the translation the states are: + +.. math:: + \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} + +.. math:: + \dot{\rho}(t) = \ddot{\rho} (t - t_f) + \dot{\rho}_0 + +.. math:: + \rho(t) = b (t - t_f)^2 + \rho_{\text{ref}} + +where + +.. math:: + b = - \frac{ \rho_{\text{ref}} - \rho_0}{2 (t_{b1} - t_f)^2} + +The switch time :math:`t_{b1}` is the simulation time at the end of the first bang segment: + +.. math:: + t_{b1} = t_0 + \frac{\Delta t_{\text{tot}}}{2} + +The total time required to complete the translation :math:`\Delta t_{\text{tot}}` is: + +.. math:: + \Delta t_{\text{tot}} = 2 \sqrt{ \frac{| \rho_{\text{ref}} - \rho_0 | }{\ddot{\rho}_{\text{max}}}} = t_f - t_0 + +Non-Smoothed Bang-Coast-Bang Profiler +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The second option to profile the linear translation is a bang-coast-bang acceleration profile with an added coast +period between the acceleration segments where the acceleration is zero. Similar to the previous profiler, if the +reference position is greater than the given initial position, the maximum acceleration value is applied +positively for the specified ramp time ``coastOptionBangDuration`` to the first segment of the translation and negatively +to the third segment of the translation. The second segment of the translation is the coast period. However, if the +reference position is less than the initial position, the acceleration is instead applied negatively during the first +segment of the translation and positively during the third segment of the translation. As a result of this acceleration +profile, the translational body's hub-relative velocity changes linearly with time and reaches a maximum in magnitude +at the end of the first segment and is constant during the coast segment. The velocity returns to zero during the +third segment. The resulting position profiled is parabolic during the first and third segments and linear during the +coast segment. + +To profile this linear motion, the scalar translating body's hub-relative states :math:`\rho`, :math:`\dot{\rho}`, and +:math:`\ddot{\rho}` are prescribed as a function of time. During the first segment of the translation the states are: + +.. math:: + \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} + +.. math:: + \dot{\rho}(t) = \ddot{\rho} (t - t_0) + \dot{\rho}_0 + +.. math:: + \rho(t) = a (t - t_0)^2 + \rho_0 + +where + +.. math:: + a = \frac{ \rho(t_{b1}) - \rho_0}{2 (t_{b1} - t_0)^2} + +and :math:`\rho(t_{b1})` is the hub-relative position at the end of the first bang segment: + +.. math:: + \rho(t_{b1}) = \pm \frac{1}{2} \ddot{\rho}_{\text{max}} t_{\text{bang}}^2 + \dot{\rho}_0 t_{\text{bang}} + \rho_0 + +.. important:: + Note the distinction between :math:`t_{b1}` and :math:`t_{\text{bang}}`. :math:`t_{\text{bang}}` is the time + duration of the acceleration segment and :math:`t_{b1}` is the simulation time at the end of the first acceleration + segment. :math:`t_{b1} = t_0 + t_{\text{bang}}` + +During the coast segment, the translational states are: + +.. math:: + \ddot{\rho}(t) = 0 + +.. math:: + \dot{\rho}(t) = \dot{\rho}(t_{b1}) = \ddot{\rho}_{\text{max}} t_{\text{bang}} + \dot{\rho}_0 + +.. math:: + \rho(t) = \dot{\rho}(t_{b1}) (t - t_{b1}) + \rho(t_{b1}) + +During the third segment, the translational states are + +.. math:: + \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} + +.. math:: + \dot{\rho}(t) = \ddot{\rho} (t - t_f) + \dot{\rho}_0 + +.. math:: + \rho(t) = b (t - t_f)^2 + \rho_{\text{ref}} + +where + +.. math:: + b = - \frac{ \rho_{\text{ref}} - \rho(t_c) }{(t_c - t_f)^2} + +Here :math:`\rho(t_c)` is the hub-relative position at the end of the coast segment: + +.. math:: + \rho(t_c) = \rho(t_{b1}) + \Delta \rho_{\text{coast}} + +and :math:`\Delta \rho_{\text{coast}}` is the distance traveled during the coast segment: + +.. math:: + \Delta \rho_{\text{coast}} = (\rho_{\text{ref}} - \rho_0) - 2 (\rho(t_{b1}) - \rho_0) + +:math:`t_c` is the simulation time at the end of the coast segment: + +.. math:: + t_c = t_{b1} + \frac{\Delta \rho_{\text{coast}}}{\dot{\rho}(t_{b1})} + +Using the given translation axis ``transHat_M``, the scalar states are then transformed to the prescribed translational +states ``r_FM_M``, ``rPrime_FM_M``, and ``rPrimePrime_FM_M``. The states are then written to the +:ref:`PrescribedTranslationMsgPayload` module output message. + +Smoothed Bang-Bang Profiler +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The third option to profile the linear translation is a smoothed bang-bang acceleration profile. This option is selected +by setting the module variable ``smoothingDuration`` to a nonzero value. This profiler uses cubic splines to construct +a continuous acceleration profiler across the entire translation. Similar to the non-smoothed bang-bang profiler, +this option smooths the acceleration between the given maximum acceleration values. +To profile this motion, the translational body's hub-relative scalar states :math:`\rho`, :math:`\dot{\rho}`, and +:math:`\ddot{\rho}` are prescribed as a function of time and the translational motion is split into five different +segments. + +The first segment smooths the acceleration from zero to the user-specified maximum acceleration value in the given +time ``smoothingDuration``. If the given reference position is greater than the given initial position, the +acceleration is smoothed positively to the given maximum acceleration value. If the given reference position is less +than the given initial position, the acceleration is smoothed from zero to the negative maximum acceleration value. +During this phase, the scalar hub-relative states are: + +.. math:: + \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{3 (t - t_0)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_0)^3}{t_{\text{smooth}}^3} \right) + +.. math:: + \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_0)^3}{t_{\text{smooth}}^2} - \frac{(t - t_0)^4}{2 t_{\text{smooth}}^3} \right) + +.. math:: + \rho(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_0)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_0)^5}{10 t_{\text{smooth}}^3} \right) + +The second segment is the first bang segment where the maximum acceleration value is applied either positively or +negatively as discussed previously. The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} + +.. math:: + \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} (t - t_{s1}) + \dot{\rho}(t_{s1}) + +.. math:: + \rho(t) = \pm \frac{\ddot{\rho}_{\text{max}} (t - t_{s1})^2}{2} + \dot{\rho}(t_{s1})(t - t_{s1}) + \rho(t_{s1}) + +where :math:`t_{s1}` is the time at the end of the first smoothing segment: + +.. math:: + t_{s1} = t_0 + t_{\text{smooth}} + +The third segment smooths the acceleration from the current maximum acceleration value to the opposite magnitude maximum +acceleration value. The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( 1 - \frac{3 (t - t_{b1})^2}{2 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^3}{2 t_{\text{smooth}}^3} \right) + +.. math:: + \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( (t - t_{b1}) - \frac{(t - t_{b1})^3}{2 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^4}{8 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_{b1}) + +.. math:: + \rho(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_{b1})^2}{2} - \frac{(t - t_{b1})^4}{8 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^5}{40 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_{b1})(t - t_{b1}) + \rho(t_{b1}) + +where :math:`t_{b1}` is the time at the end of the first bang segment: + +.. math:: + t_{b1} = t_{s1} + t_{\text{bang}} + +The fourth segment is the second bang segment where the maximum acceleration value is applied either positively or +negatively as discussed previously. The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} + +.. math:: + \dot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} (t - t_{s2}) + \dot{\rho}(t_{s2}) + +.. math:: + \rho(t) = \mp \frac{\ddot{\rho}_{\text{max}} (t - t_{s2})^2}{2} + \dot{\rho}(t_{s2})(t - t_{s2}) + \rho(t_{s2}) + +where :math:`t_{s2}` is the time at the end of the second smoothing segment: + +.. math:: + t_{s2} = t_{b1} + t_{\text{smooth}} + +The fifth segment is the third and final smoothing segment where the acceleration returns to zero. The scalar +hub-relative states during this phase are: + +.. math:: + \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} \left ( -1 + \frac{3(t - t_{b2})^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_{b2})^3}{t_{\text{smooth}}^3} \right ) + +.. math:: + \dot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} \left ( -(t - t_{b2}) + \frac{(t - t_{b2})^3}{t_{\text{smooth}}^2} - \frac{(t - t_{b2})^4}{2 t_{\text{smooth}}^3} \right ) + \dot{\rho}(t_{b2}) + +.. math:: + \rho(t) = \mp \ddot{\rho}_{\text{max}} \left ( \frac{(t - t_{b2})^2}{2} + \frac{(t - t_{b2})^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_{b2})^5}{10 t_{\text{smooth}}^3} \right ) + \dot{\rho}(t_{b2})(t - t_{b2}) + \rho(t_{b2}) + +where :math:`t_{b2}` is the time at the end of the second bang segment: + +.. math:: + t_{b2} = t_{s2} + t_{\text{bang}} + +Smoothed Bang-Coast-Bang Profiler +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The fourth option to profile the linear translation is a smoothed bang-coast-bang acceleration profile. This option is +selected by setting the module variables ``coastOptionBangDuration`` and ``smoothingDuration`` to nonzero values. +This profiler uses cubic splines to construct a continuous acceleration profiler across the entire translation. +To profile this motion, the translational body's hub-relative scalar states :math:`\rho`, :math:`\dot{\rho}`, and +:math:`\ddot{\rho}` are prescribed as a function of time and the translational motion is split into seven different +segments. + +The first segment smooths the acceleration from zero to the user-specified maximum acceleration value in the given +time ``smoothingDuration``. If the given reference position is greater than the given initial position, the +acceleration is smoothed positively to the given maximum acceleration value. If the given reference position is less +than the given initial position, the acceleration is smoothed from zero to the negative maximum acceleration value. +During this phase, the scalar hub-relative states are: + +.. math:: + \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{3 (t - t_0)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_0)^3}{t_{\text{smooth}}^3} \right) + +.. math:: + \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_0)^3}{t_{\text{smooth}}^2} - \frac{(t - t_0)^4}{2 t_{\text{smooth}}^3} \right) + +.. math:: + \rho(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_0)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_0)^5}{10 t_{\text{smooth}}^3} \right) + +The second segment is the first bang segment where the maximum acceleration value is applied either positively or +negatively as discussed previously. The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} + +.. math:: + \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} (t - t_{s1}) + \dot{\rho}(t_{s1}) + +.. math:: + \rho(t) = \pm \frac{\ddot{\rho}_{\text{max}} (t - t_{s1})^2}{2} + \dot{\rho}(t_{s1})(t - t_{s1}) + \rho(t_{s1}) + +where :math:`t_{s1}` is the time at the end of the first smoothing segment. + +The third segment prior to the coast phase smooths the acceleration from the current maximum acceleration value to zero. +The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( 1 - \frac{3 (t - t_{b1})^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_{b1})^3}{t_{\text{smooth}}^3} \right) + +.. math:: + \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left( (t - t_{b1}) - \frac{(t - t_{b1})^3}{t_{\text{smooth}}^2} - \frac{(t - t_{b1})^4}{2 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_{b1}) + +.. math:: + \rho(t) = \pm \ddot{\rho}_{\text{max}} \left( \frac{(t - t_{b1})^2}{2} - \frac{(t - t_{b1})^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_{b1})^5}{10 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_{b1})(t - t_{b1}) + \rho(t_{b1}) + +where :math:`t_{b1}` is the time at the end of the first bang segment. + +The fourth segment is the coast segment where the translational states are: + +.. math:: + \ddot{\rho}(t) = 0 + +.. math:: + \dot{\rho}(t) = \dot{\rho}(t_{s2}) + +.. math:: + \rho(t) = \dot{\rho}(t_{s2}) (t - t_{s2}) + \rho(t_{s2}) + +where :math:`t_{s2}` is the time at the end of the second smoothing segment. + +The fifth segment smooths the acceleration from zero to the maximum acceleration value prior to the second bang segment. +The translational states during this phase are: + +.. math:: + \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} \left( \frac{3 (t - t_c)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_c)^3}{t_{\text{smooth}}^3} \right) + +.. math:: + \dot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} \left( \frac{(t - t_c)^3}{t_{\text{smooth}}^2} - \frac{(t - t_c)^4}{2 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_c) + +.. math:: + \rho(t) = \mp \ddot{\rho}_{\text{max}} \left( \frac{(t - t_c)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_c)^5}{10 t_{\text{smooth}}^3} \right) + \dot{\rho}(t_c) (t - t_c) + \rho(t_c) + +where :math:`t_c` is the time at the end of the coast segment. + +The sixth segment is the second bang segment where the maximum acceleration value is applied either positively or +negatively as discussed previously. The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} + +.. math:: + \dot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} (t - t_{s3}) + \dot{\rho}(t_{s3}) + +.. math:: + \rho(t) = \mp \frac{\ddot{\rho}_{\text{max}} (t - t_{s3})^2}{2} + \dot{\rho}(t_{s3})(t - t_{s3}) + \rho(t_{s3}) + +where :math:`t_{s3}` is the time at the end of the third smoothing segment. + +The seventh segment is the fourth and final smoothing segment where the acceleration returns to zero. The scalar +hub-relative states during this phase are: + +.. math:: + \ddot{\rho}(t) = \mp \ddot{\rho}_{\text{max}} \left (\frac{3(t_f - t)^2}{t_{\text{smooth}}^2} - \frac{2 (t_f - t)^3}{t_{\text{smooth}}^3} \right ) + +.. math:: + \dot{\rho}(t) = \pm \ddot{\rho}_{\text{max}} \left (\frac{(t_f - t)^3}{t_{\text{smooth}}^2} - \frac{(t_f - t)^4}{2 t_{\text{smooth}}^3} \right ) + +.. math:: + \rho(t) = \mp \ddot{\rho}_{\text{max}} \left (\frac{(t_f - t)^4}{4 t_{\text{smooth}}^2} - \frac{(t_f - t)^5}{10 t_{\text{smooth}}^3} \right ) + \rho_{\text{ref}} + +where :math:`t_f` is the time at the end of the translation: + +Module Testing +^^^^^^^^^^^^^^ +The unit test for this module ensures that the profiled linear translation for a secondary rigid body relative to +the spacecraft hub is properly computed for several different simulation configurations. The unit test profiles +two successive translations to ensure the module is correctly configured. The secondary body's initial scalar +translational position relative to the spacecraft hub is varied, along with the two final reference positions +and the maximum translational acceleration. + +The unit test also tests four different methods of profiling the translation. Two profilers prescribe a pure +bang-bang or bang-coast-bang linear acceleration profile for the translation. The bang-bang option results in +the fastest possible translation; while the bang-coast-bang option includes a coast period with zero acceleration +between the acceleration segments. The other two profilers apply smoothing to the bang-bang and bang-coast-bang +acceleration profiles so that the secondary body hub-relative rates start and end at zero. + +To verify the module functionality, the final position at the end of each translation segment is checked to match +the specified reference positions. Additionally, for the smoothed profiler options, the numerical derivative of the +profiled displacements and velocities is determined across the entire simulation. These numerical derivatives are +checked with the module's acceleration and velocity profiles to ensure the profiled acceleration is correctly +integrated in the module to obtain the displacements and velocities. + +User Guide +---------- +The general inputs to this module that must be set by the user are the translational axis expressed as a +unit vector in mount frame components ``transHat_M``, the initial translational body position relative to the hub-fixed +mount frame ``transPosInit``, the reference position relative to the mount frame ``transPosRef``, and the maximum scalar +linear acceleration for the translation ``transAccelMax``. The optional inputs ``coastOptionBangDuration`` and +``smoothingDuration`` can be set by the user to select the specific type of profiler that is desired. If these variables +are not set by the user, the module defaults to the non-smoothed bang-bang profiler. If only the variable +``coastOptionBangDuration`` is set to a nonzero value, the bang-coast-bang profiler is selected. If only the variable +``smoothingDuration`` is set to a nonzero value, the smoothed bang-bang profiler is selected. If both variables are +set to nonzero values, the smoothed bang-coast-bang profiler is selected. + +This section is to outline the steps needed to setup the prescribed linear translational module in python using Xmera. + +#. Import the prescribedLinearTranslation class: + +.. code-block:: python + + from Xmera.simulation import prescribedLinearTranslation + +#. Create an instantiation of the module:: + + prescribedLinearTrans = prescribedLinearTranslation.PrescribedLinearTranslation() + +#. Define all of the configuration data associated with the module. For example, to configure the smoothed bang-coast-bang option: + +.. code-block:: python + + prescribedLinearTrans.modelTag = "prescribedLinearTranslation" + prescribedLinearTrans.setTransHat_M(np.array([0.5, 0.0, 0.5 * np.sqrt(3)])) + prescribedLinearTrans.setTransAccelMax(0.01) # [m/s^2] + prescribedLinearTrans.setTransPosInit(0.5) # [m] + prescribedLinearTrans.setCoastRampDuration(1.0) # [s] + prescribedLinearTrans.setSmoothingDuration(1.0) # [s] + +#. Connect a :ref:`LinearTranslationRigidBodyMsgPayload` message for the translating body reference position to the module. For example, the user can create a stand-alone message to specify the reference position: + +.. code-block:: python + + linearTranslationRigidBodyMessageData = messaging.LinearTranslationRigidBodyMsgPayload() + linearTranslationRigidBodyMessageData.rho = 1.0 # [m] + linearTranslationRigidBodyMessageData.rhoDot = 0.0 # [m/s] + linearTranslationRigidBodyMessage = messaging.LinearTranslationRigidBodyMsg().write(linearTranslationRigidBodyMessageData) + +#. Subscribe the reference message to the prescribedTranslation module input message:: + + prescribedLinearTrans.linearTranslationRigidBodyInMsg.subscribeTo(linearTranslationRigidBodyMessage) + +#. Add the module to the task list:: + + unitTestSim.AddModelToTask(unitTaskName, prescribedLinearTrans) diff --git a/src/simulation/deviceInterface/prescribedRotation1DOF/prescribedRotation1DOF.rst b/src/simulation/deviceInterface/prescribedRotation1DOF/prescribedRotation1DOF.rst index 4c0da4ed3..37851ed19 100644 --- a/src/simulation/deviceInterface/prescribedRotation1DOF/prescribedRotation1DOF.rst +++ b/src/simulation/deviceInterface/prescribedRotation1DOF/prescribedRotation1DOF.rst @@ -1,483 +1,489 @@ -Executive Summary ------------------ -This module profiles a 1 DOF rotation for a spinning rigid body connected to a rigid spacecraft hub. The body frame -of the spinning body is designated by the frame :math:`\mathcal{F}`. The spinning body's states are profiled -relative to a hub-fixed frame :math:`\mathcal{M}`. The :ref:`PrescribedRotationMsgPayload` message -is used to output the prescribed rotational states from the module. The prescribed states profiled in this module -are: ``omega_FM_F``, ``omegaPrime_FM_F``, and ``sigma_FM``. This module has four options to profile the spinning body -rotation. The first option is a bang-bang acceleration profile that minimizes the time required for the rotation. -The second option is a bang-coast-bang acceleration profile that adds a coast period of zero acceleration between the -acceleration ramp segments. The third option is a smoothed bang-bang acceleration profile that uses cubic splines to -construct a continuous acceleration profile across the entire rotation. The fourth option is a smoothed -bang-coast-bang acceleration profile. - -The module defaults to the non-smoothed bang-bang option with no coast period. If the coast option is desired, the -user must set the module variable ``coastOptionBangDuration`` to a nonzero value. If smoothing is desired, -the module variable ``smoothingDuration`` must be set to a nonzero value. - -.. important:: - Note that this module assumes the initial and final spinning body hub-relative angular rates are zero. - -The general inputs to this module that must be set by the user are the spinning body rotation axis expressed as a -unit vector in mount frame components ``rotHat_M``, the initial spinning body angle relative to the hub-fixed -mount frame ``thetaInit``, the reference angle relative to the mount frame ``thetaRef``, and the maximum scalar angular -acceleration for the rotation ``thetaDDotMax``. The optional inputs ``coastOptionBangDuration`` and -``smoothingDuration`` can be set by the user to select the specific type of profiler that is desired. If these variables -are not set by the user, the module defaults to the non-smoothed bang-bang profiler. If only the variable -``coastOptionBangDuration`` is set to a nonzero value, the bang-coast-bang profiler is selected. If only the variable -``smoothingDuration`` is set to a nonzero value, the smoothed bang-bang profiler is selected. If both variables are -set to nonzero values, the smoothed bang-coast-bang profiler is selected. - -.. important:: - To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` - dynamics module. This ensures the spinning body's states are correctly incorporated into the spacecraft dynamics. - See the example script :ref:`scenarioDeployingSolarArrays` for more information about how to set up hub-relative - multi-body prescribed motion using the state effector module together with this profiler module. - -Message Connection Descriptions -------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description -provides information on what the message is used for. - -.. list-table:: Module I/O Messages - :widths: 25 25 50 - :header-rows: 1 - - * - Msg Variable Name - - Msg Type - - Description - * - spinningBodyInMsg - - :ref:`HingedRigidBodyMsgPayload` - - input msg with the spinning body reference states - * - spinningBodyOutMsg - - :ref:`HingedRigidBodyMsgPayload` - - output message with the scalar spinning body states - * - spinningBodyOutMsgC - - :ref:`HingedRigidBodyMsgPayload` - - C-wrapoped output message with the scalar spinning body states - * - prescribedRotationOutMsg - - :ref:`PrescribedRotationMsgPayload` - - output message with the prescribed spinning body rotational states - * - prescribedRotationOutMsgC - - :ref:`PrescribedRotationMsgPayload` - - C-wrapped output message with the prescribed spinning body rotational states - -Detailed Module Description ---------------------------- - -Non-Smoothed Bang-Bang Profiler -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The first option to profile the spinning body rotation is a pure bang-bang acceleration profile. If the spinning -body reference angle is greater than the given initial angle, the user-specified maximum angular acceleration value -is applied positively to the first half of the rotation and negatively to the second half of the rotation. -However, if the reference angle is less than the initial spinning body angle, the acceleration is instead applied -negatively during the first half of the rotation and positively during the second half of the rotation. As a result -of this acceleration profile, the spinning body's angle rate changes linearly with time and reaches a maximum -in magnitude halfway through the rotation. Note that the angle rate is assumed to both start and end at zero -in this module. The resulting spinning body hub-relative angle for the rotation is parabolic in time. - -To profile this spinning body motion, the spinning body's hub-relative scalar states :math:`\theta`, -:math:`\dot{\theta}`, and :math:`\ddot{\theta}` are prescribed as a function of time. During the first half of the -rotation the states are: - -.. math:: - \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} - -.. math:: - \dot{\theta}(t) = \ddot{\theta} (t - t_0) + \dot{\theta}_0 - -.. math:: - \theta(t) = a (t - t_0)^2 + \theta_0 - -where - -.. math:: - a = \frac{ \theta_{\text{ref}} - \theta_0}{2 (t_{b1} - t_0)^2} - -During the second half of the rotation the states are: - -.. math:: - \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} - -.. math:: - \dot{\theta}(t) = \ddot{\theta} (t - t_f) + \dot{\theta}_0 - -.. math:: - \theta(t) = b (t - t_f)^2 + \theta_{\text{ref}} - -where - -.. math:: - b = - \frac{ \theta_{\text{ref}} - \theta_0}{2 (t_{b1} - t_f)^2} - -The switch time :math:`t_{b1}` is the simulation time at the end of the first bang segment: - -.. math:: - t_{b1} = t_0 + \frac{\Delta t_{\text{tot}}}{2} - -The total time required to complete the rotation :math:`\Delta t_{\text{tot}}` is: - -.. math:: - \Delta t_{\text{tot}} = 2 \sqrt{ \frac{| \theta_{\text{ref}} - \theta_0 | }{\ddot{\theta}_{\text{max}}}} = t_f - t_0 - -Non-Smoothed Bang-Coast-Bang Profiler -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The second option to profile the spinning body rotation is a bang-coast-bang acceleration profile with an added coast -period between the acceleration segments where the acceleration is zero. Similar to the previous profiler, if the -spinning body reference angle is greater than the given initial angle, the maximum angular acceleration value is applied -positively for the specified ramp time ``coastOptionBangDuration`` to the first segment of the rotation and negatively -to the third segment of the rotation. The second segment of the rotation is the coast period. However, if the reference -angle is less than the initial spinning body angle, the acceleration is instead applied negatively during the first -segment of the rotation and positively during the third segment of the rotation. As a result of this acceleration -profile, the spinning body's hub-relative angle rate changes linearly with time and reaches a maximum in magnitude -at the end of the first segment and is constant during the coast segment. The angle rate returns to zero during the third -segment. The resulting spinning body angle for the rotation is parabolic during the first and third segments and linear -during the coast segment. - -To profile this spinning body motion, the spinning body's hub-relative scalar states :math:`\theta`, -:math:`\dot{\theta}`, and :math:`\ddot{\theta}` are prescribed as a function of time. During the first segment of the -rotation the states are: - -.. math:: - \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} - -.. math:: - \dot{\theta}(t) = \ddot{\theta} (t - t_0) + \dot{\theta}_0 - -.. math:: - \theta(t) = a (t - t_0)^2 + \theta_0 - -where - -.. math:: - a = \frac{ \theta(t_{b1}) - \theta_0}{2 (t_{b1} - t_0)^2} - -and :math:`\theta(t_{b1})` is the spinning body angle at the end of the first bang segment: - -.. math:: - \theta(t_{b1}) = \pm \frac{1}{2} \ddot{\theta}_{\text{max}} t_{\text{bang}}^2 - + \dot{\theta}_0 t_{\text{bang}} + \theta_0 - -.. important:: - Note the distinction between :math:`t_{b1}` and :math:`t_{\text{bang}}`. :math:`t_{\text{bang}}` is the time - duration of the acceleration segment configured by the user as the module variable ``coastOptionBangDuration``. - :math:`t_{b1}` is the simulation time at the end of the first acceleration segment. - :math:`t_{b1} = t_0 + t_{\text{bang}}` - -During the coast segment, the rotation states are: - -.. math:: - \ddot{\theta}(t) = 0 - -.. math:: - \dot{\theta}(t) = \dot{\theta}(t_{b1}) = \ddot{\theta}_{\text{max}} t_{\text{bang}} + \dot{\theta}_0 - -.. math:: - \theta(t) = \dot{\theta}(t_{b1}) (t - t_{b1}) + \theta(t_{b1}) - -During the third segment, the rotation states are - -.. math:: - \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} - -.. math:: - \dot{\theta}(t) = \ddot{\theta} (t - t_f) + \dot{\theta}_0 - -.. math:: - \theta(t) = b (t - t_f)^2 + \theta_{\text{ref}} - -where - -.. math:: - b = - \frac{ \theta_{\text{ref}} - \theta(t_c) }{(t_c - t_f)^2} - -Here :math:`\theta(t_c)` is the spinning body angle at the end of the coast segment: - -.. math:: - \theta(t_c) = \theta(t_{b1}) + \Delta \theta_{\text{coast}} - -and :math:`\Delta \theta_{\text{coast}}` is the angle traveled during the coast segment: - -.. math:: - \Delta \theta_{\text{coast}} = (\theta_{\text{ref}} - \theta_0) - 2 (\theta(t_{b1}) - \theta_0) - -:math:`t_c` is the simulation time at the end of the coast segment: - -.. math:: - t_c = t_{b1} + \frac{\Delta \theta_{\text{coast}}}{\dot{\theta}(t_{b1})} - -Using the given rotation axis ``rotHat_M``, the scalar states are then transformed to the spinning body -rotational states ``omega_FM_F``, ``omegaPrime_FM_F``, and ``sigma_FM``. The states are then written to the -:ref:`PrescribedRotationMsgPayload` module output message. - -Smoothed Bang-Bang Profiler -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The third option to profile the rotation is a smoothed bang-bang acceleration profile. This option is selected -by setting the module variable ``smoothingDuration`` to a nonzero value. This profiler uses cubic splines to construct -a continuous acceleration profiler across the entire rotation. Similar to the non-smoothed bang-bang profiler, -this option smooths the acceleration between the given maximum acceleration values. -To profile this motion, the spinning body's hub-relative scalar states :math:`\theta`, :math:`\dot{\theta}`, and -:math:`\ddot{\theta}` are prescribed as a function of time and the rotational motion is split into five different -segments. - -The first segment smooths the acceleration from zero to the user-specified maximum acceleration value in the given -time ``smoothingDuration``. If the given reference angle is greater than the given initial angle, the -acceleration is smoothed positively to the given maximum acceleration value. If the given reference angle is less -than the given initial angle, the acceleration is smoothed from zero to the negative maximum acceleration value. -During this phase, the scalar hub-relative states are: - -.. math:: - \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{3 (t - t_0)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_0)^3}{t_{\text{smooth}}^3} \right) - -.. math:: - \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_0)^3}{t_{\text{smooth}}^2} - \frac{(t - t_0)^4}{2 t_{\text{smooth}}^3} \right) - -.. math:: - \theta(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_0)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_0)^5}{10 t_{\text{smooth}}^3} \right) + \theta_0 - -The second segment is the first bang segment where the maximum acceleration value is applied either positively or -negatively as discussed previously. The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} - -.. math:: - \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} (t - t_{s1}) + \dot{\theta}(t_{s1}) - -.. math:: - \theta(t) = \pm \frac{\ddot{\theta}_{\text{max}} (t - t_{s1})^2}{2} + \dot{\theta}(t_{s1})(t - t_{s1}) + \theta(t_{s1}) - -where :math:`t_{s1}` is the time at the end of the first smoothing segment: - -.. math:: - t_{s1} = t_0 + t_{\text{smooth}} - -The third segment smooths the acceleration from the current maximum acceleration value to the opposite magnitude maximum -acceleration value. The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( 1 - \frac{3 (t - t_{b1})^2}{2 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^3}{2 t_{\text{smooth}}^3} \right) - -.. math:: - \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( (t - t_{b1}) - \frac{(t - t_{b1})^3}{2 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^4}{8 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_{b1}) - -.. math:: - \theta(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_{b1})^2}{2} - \frac{(t - t_{b1})^4}{8 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^5}{40 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_{b1})(t - t_{b1}) + \theta(t_{b1}) - -where :math:`t_{b1}` is the time at the end of the first bang segment: - -.. math:: - t_{b1} = t_{s1} + t_{\text{bang}} - -The fourth segment is the second bang segment where the maximum acceleration value is applied either positively or -negatively as discussed previously. The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} - -.. math:: - \dot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} (t - t_{s2}) + \dot{\theta}(t_{s2}) - -.. math:: - \theta(t) = \mp \frac{\ddot{\theta}_{\text{max}} (t - t_{s2})^2}{2} + \dot{\theta}(t_{s2})(t - t_{s2}) + \theta(t_{s2}) - -where :math:`t_{s2}` is the time at the end of the second smoothing segment: - -.. math:: - t_{s2} = t_{b1} + t_{\text{smooth}} - -The fifth segment is the third and final smoothing segment where the acceleration returns to zero. The scalar -hub-relative states during this phase are: - -.. math:: - \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} \left ( -1 + \frac{3(t - t_{b2})^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_{b2})^3}{t_{\text{smooth}}^3} \right ) - -.. math:: - \dot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} \left ( -(t - t_{b2}) + \frac{(t - t_{b2})^3}{t_{\text{smooth}}^2} - \frac{(t - t_{b2})^4}{2 t_{\text{smooth}}^3} \right ) + \dot{\theta}(t_{b2}) - -.. math:: - \theta(t) = \mp \ddot{\theta}_{\text{max}} \left ( \frac{(t - t_{b2})^2}{2} + \frac{(t - t_{b2})^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_{b2})^5}{10 t_{\text{smooth}}^3} \right ) + \dot{\theta}(t_{b2})(t - t_{b2}) + \theta(t_{b2}) - -where :math:`t_{b2}` is the time at the end of the second bang segment: - -.. math:: - t_{b2} = t_{s2} + t_{\text{bang}} - -Smoothed Bang-Coast-Bang Profiler -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The fourth option to profile the rotation is a smoothed bang-coast-bang acceleration profile. This option is -selected by setting the module variables ``coastOptionBangDuration`` and ``smoothingDuration`` to nonzero values. -This profiler uses cubic splines to construct a continuous acceleration profiler across the entire rotation. -To profile this motion, the spinning body's hub-relative scalar states :math:`\theta`, :math:`\dot{\theta}`, and -:math:`\ddot{\theta}` are prescribed as a function of time and the rotational motion is split into seven different -segments. - -The first segment smooths the acceleration from zero to the user-specified maximum acceleration value in the given -time ``smoothingDuration``. If the given reference angle is greater than the given initial angle, the -acceleration is smoothed positively to the given maximum acceleration value. If the given reference angle is less -than the given initial angle, the acceleration is smoothed from zero to the negative maximum acceleration value. -During this phase, the scalar hub-relative states are: - -.. math:: - \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{3 (t - t_0)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_0)^3}{t_{\text{smooth}}^3} \right) - -.. math:: - \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_0)^3}{t_{\text{smooth}}^2} - \frac{(t - t_0)^4}{2 t_{\text{smooth}}^3} \right) - -.. math:: - \theta(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_0)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_0)^5}{10 t_{\text{smooth}}^3} \right) + \theta_0 - -The second segment is the first bang segment where the maximum acceleration value is applied either positively or -negatively as discussed previously. The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} - -.. math:: - \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} (t - t_{s1}) + \dot{\theta}(t_{s1}) - -.. math:: - \theta(t) = \pm \frac{\ddot{\theta}_{\text{max}} (t - t_{s1})^2}{2} + \dot{\theta}(t_{s1})(t - t_{s1}) + \theta(t_{s1}) - -where :math:`t_{s1}` is the time at the end of the first smoothing segment. - -The third segment prior to the coast phase smooths the acceleration from the current maximum acceleration value to zero. -The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( 1 - \frac{3 (t - t_{b1})^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_{b1})^3}{t_{\text{smooth}}^3} \right) - -.. math:: - \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( (t - t_{b1}) - \frac{(t - t_{b1})^3}{t_{\text{smooth}}^2} - \frac{(t - t_{b1})^4}{2 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_{b1}) - -.. math:: - \theta(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_{b1})^2}{2} - \frac{(t - t_{b1})^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_{b1})^5}{10 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_{b1})(t - t_{b1}) + \theta(t_{b1}) - -where :math:`t_{b1}` is the time at the end of the first bang segment. - -The fourth segment is the coast segment where the rotational states are: - -.. math:: - \ddot{\theta}(t) = 0 - -.. math:: - \dot{\theta}(t) = \dot{\theta}(t_{s2}) - -.. math:: - \theta(t) = \dot{\theta}(t_{s2}) (t - t_{s2}) + \theta(t_{s2}) - -where :math:`t_{s2}` is the time at the end of the second smoothing segment. - -The fifth segment smooths the acceleration from zero to the maximum acceleration value prior to the second bang segment. -The rotational states during this phase are: - -.. math:: - \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} \left( \frac{3 (t - t_c)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_c)^3}{t_{\text{smooth}}^3} \right) - -.. math:: - \dot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} \left( \frac{(t - t_c)^3}{t_{\text{smooth}}^2} - \frac{(t - t_c)^4}{2 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_c) - -.. math:: - \theta(t) = \mp \ddot{\theta}_{\text{max}} \left( \frac{(t - t_c)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_c)^5}{10 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_c) (t - t_c) + \theta(t_c) - -where :math:`t_c` is the time at the end of the coast segment. - -The sixth segment is the second bang segment where the maximum acceleration value is applied either positively or -negatively as discussed previously. The scalar hub-relative states during this phase are: - -.. math:: - \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} - -.. math:: - \dot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} (t - t_{s3}) + \dot{\theta}(t_{s3}) - -.. math:: - \theta(t) = \mp \frac{\ddot{\theta}_{\text{max}} (t - t_{s3})^2}{2} + \dot{\theta}(t_{s3})(t - t_{s3}) + \theta(t_{s3}) - -where :math:`t_{s3}` is the time at the end of the third smoothing segment. - -The seventh segment is the fourth and final smoothing segment where the acceleration returns to zero. The scalar -hub-relative states during this phase are: - -.. math:: - \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} \left (\frac{3(t_f - t)^2}{t_{\text{smooth}}^2} - \frac{2 (t_f - t)^3}{t_{\text{smooth}}^3} \right ) - -.. math:: - \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left (\frac{(t_f - t)^3}{t_{\text{smooth}}^2} - \frac{(t_f - t)^4}{2 t_{\text{smooth}}^3} \right ) - -.. math:: - \theta(t) = \mp \ddot{\theta}_{\text{max}} \left (\frac{(t_f - t)^4}{4 t_{\text{smooth}}^2} - \frac{(t_f - t)^5}{10 t_{\text{smooth}}^3} \right ) + \theta_{\text{ref}} - -where :math:`t_f` is the time at the end of the rotation: - -Module Testing -^^^^^^^^^^^^^^ -The unit test for this module ensures that the profiled 1 DOF rotation for a secondary rigid body relative to -the spacecraft hub is properly computed for several different simulation configurations. The unit test profiles -two successive rotations to ensure the module is correctly configured. The initial spinning body angle relative -to the spacecraft hub is varied, along with the two final reference angles and the maximum angular acceleration -for the rotation. - -The unit test also tests four different methods of profiling the rotation. Two profilers prescribe a pure -bang-bang or bang-coast-bang angular acceleration profile for the rotation. The bang-bang option results in -the fastest possible rotation; while the bang-coast-bang option includes a coast period with zero acceleration -between the acceleration segments. The other two profilers apply smoothing to the bang-bang and bang-coast-bang -acceleration profiles so that the spinning body hub-relative rates start and end at zero. - -To verify the module functionality, the final angle at the end of each rotation is checked to match the specified -reference angle. Additionally, for the smoothed profiler options, the numerical derivative of the profiled angles -and their rates is determined across the entire simulation. These numerical derivatives are checked with the module's -acceleration and rate profiles to ensure the profiled acceleration is correctly integrated in the module to obtain -the angles and their rates. - -User Guide ----------- -The general inputs to this module that must be set by the user are the spinning body rotation axis expressed as a -unit vector in mount frame components ``rotHat_M``, the initial spinning body angle relative to the hub-fixed -mount frame ``thetaInit``, the reference angle relative to the mount frame ``thetaRef``, and the maximum scalar angular -acceleration for the rotation ``thetaDDotMax``. The optional inputs ``coastOptionBangDuration`` and -``smoothingDuration`` can be set by the user to select the specific type of profiler that is desired. If these variables -are not set by the user, the module defaults to the non-smoothed bang-bang profiler. If only the variable -``coastOptionBangDuration`` is set to a nonzero value, the bang-coast-bang profiler is selected. If only the variable -``smoothingDuration`` is set to a nonzero value, the smoothed bang-bang profiler is selected. If both variables are -set to nonzero values, the smoothed bang-coast-bang profiler is selected. - -This section is to outline the steps needed to set up the prescribed rotational 1 DOF module in python using Xmera. - -#. Import the prescribedRotation1DOF class:: - - from Xmera.simulation import prescribedRotation1DOF - -#. Create an instantiation of the module:: - - prescribedRot1DOF = prescribedRotation1DOF.PrescribedRotation1DOF() - -#. Define all of the configuration data associated with the module. For example, to configure the smoothed bang-coast-bang option:: - - prescribedRot1DOF.modelTag = "prescribedRotation1DOF" - prescribedRot1DOF.setRotHat_M(np.array([0.0, 1.0, 0.0])) - prescribedRot1DOF.setThetaDDotMax(macros.D2R * 1.0) # [rad/s^2] - prescribedRot1DOF.setThetaInit(macros.D2R * 10.0) # [rad] - prescribedRot1DOF.setCoastOptionBangDuration(3.0) # [s] - prescribedRot1DOF.setSmoothingDuration(1.0) # [s] - -#. Connect a :ref:`HingedRigidBodyMsgPayload` message for the spinning body reference angle to the module. For example, the user can create a stand-alone message to specify the reference angle:: - - hingedRigidBodyMessageData = messaging.HingedRigidBodyMsgPayload() - hingedRigidBodyMessageData.theta = macros.D2R * 90.0 # [rad] - hingedRigidBodyMessageData.thetaDot = 0.0 # [rad/s] - hingedRigidBodyMessage = messaging.HingedRigidBodyMsg().write(hingedRigidBodyMessageData) - -#. Subscribe the spinning body reference message to the prescribedRotation1DOF module input message:: - - prescribedRot1DOF.spinningBodyInMsg.subscribeTo(hingedRigidBodyMessage) - -#. Add the module to the task list:: - - unitTestSim.AddModelToTask(unitTaskName, prescribedRot1DOF) +Executive Summary +----------------- +This module profiles a 1 DOF rotation for a spinning rigid body connected to a rigid spacecraft hub. The body frame +of the spinning body is designated by the frame :math:`\mathcal{F}`. The spinning body's states are profiled +relative to a hub-fixed frame :math:`\mathcal{M}`. The :ref:`PrescribedRotationMsgPayload` message +is used to output the prescribed rotational states from the module. The prescribed states profiled in this module +are: ``omega_FM_F``, ``omegaPrime_FM_F``, and ``sigma_FM``. This module has four options to profile the spinning body +rotation. The first option is a bang-bang acceleration profile that minimizes the time required for the rotation. +The second option is a bang-coast-bang acceleration profile that adds a coast period of zero acceleration between the +acceleration ramp segments. The third option is a smoothed bang-bang acceleration profile that uses cubic splines to +construct a continuous acceleration profile across the entire rotation. The fourth option is a smoothed +bang-coast-bang acceleration profile. + +The module defaults to the non-smoothed bang-bang option with no coast period. If the coast option is desired, the +user must set the module variable ``coastOptionBangDuration`` to a nonzero value. If smoothing is desired, +the module variable ``smoothingDuration`` must be set to a nonzero value. + +.. important:: + Note that this module assumes the initial and final spinning body hub-relative angular rates are zero. + +The general inputs to this module that must be set by the user are the spinning body rotation axis expressed as a +unit vector in mount frame components ``rotHat_M``, the initial spinning body angle relative to the hub-fixed +mount frame ``thetaInit``, the reference angle relative to the mount frame ``thetaRef``, and the maximum scalar angular +acceleration for the rotation ``thetaDDotMax``. The optional inputs ``coastOptionBangDuration`` and +``smoothingDuration`` can be set by the user to select the specific type of profiler that is desired. If these variables +are not set by the user, the module defaults to the non-smoothed bang-bang profiler. If only the variable +``coastOptionBangDuration`` is set to a nonzero value, the bang-coast-bang profiler is selected. If only the variable +``smoothingDuration`` is set to a nonzero value, the smoothed bang-bang profiler is selected. If both variables are +set to nonzero values, the smoothed bang-coast-bang profiler is selected. + +.. important:: + To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` + dynamics module. This ensures the spinning body's states are correctly incorporated into the spacecraft dynamics. + See the example script :ref:`scenarioDeployingSolarArrays` for more information about how to set up hub-relative + multi-body prescribed motion using the state effector module together with this profiler module. + +Message Connection Descriptions +------------------------------- +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description +provides information on what the message is used for. + +.. list-table:: Module I/O Messages + :widths: 25 25 50 + :header-rows: 1 + + * - Msg Variable Name + - Msg Type + - Description + * - spinningBodyInMsg + - :ref:`HingedRigidBodyMsgPayload` + - input msg with the spinning body reference states + * - spinningBodyOutMsg + - :ref:`HingedRigidBodyMsgPayload` + - output message with the scalar spinning body states + * - spinningBodyOutMsgC + - :ref:`HingedRigidBodyMsgPayload` + - C-wrapoped output message with the scalar spinning body states + * - prescribedRotationOutMsg + - :ref:`PrescribedRotationMsgPayload` + - output message with the prescribed spinning body rotational states + * - prescribedRotationOutMsgC + - :ref:`PrescribedRotationMsgPayload` + - C-wrapped output message with the prescribed spinning body rotational states + +Detailed Module Description +--------------------------- + +Non-Smoothed Bang-Bang Profiler +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The first option to profile the spinning body rotation is a pure bang-bang acceleration profile. If the spinning +body reference angle is greater than the given initial angle, the user-specified maximum angular acceleration value +is applied positively to the first half of the rotation and negatively to the second half of the rotation. +However, if the reference angle is less than the initial spinning body angle, the acceleration is instead applied +negatively during the first half of the rotation and positively during the second half of the rotation. As a result +of this acceleration profile, the spinning body's angle rate changes linearly with time and reaches a maximum +in magnitude halfway through the rotation. Note that the angle rate is assumed to both start and end at zero +in this module. The resulting spinning body hub-relative angle for the rotation is parabolic in time. + +To profile this spinning body motion, the spinning body's hub-relative scalar states :math:`\theta`, +:math:`\dot{\theta}`, and :math:`\ddot{\theta}` are prescribed as a function of time. During the first half of the +rotation the states are: + +.. math:: + \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} + +.. math:: + \dot{\theta}(t) = \ddot{\theta} (t - t_0) + \dot{\theta}_0 + +.. math:: + \theta(t) = a (t - t_0)^2 + \theta_0 + +where + +.. math:: + a = \frac{ \theta_{\text{ref}} - \theta_0}{2 (t_{b1} - t_0)^2} + +During the second half of the rotation the states are: + +.. math:: + \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} + +.. math:: + \dot{\theta}(t) = \ddot{\theta} (t - t_f) + \dot{\theta}_0 + +.. math:: + \theta(t) = b (t - t_f)^2 + \theta_{\text{ref}} + +where + +.. math:: + b = - \frac{ \theta_{\text{ref}} - \theta_0}{2 (t_{b1} - t_f)^2} + +The switch time :math:`t_{b1}` is the simulation time at the end of the first bang segment: + +.. math:: + t_{b1} = t_0 + \frac{\Delta t_{\text{tot}}}{2} + +The total time required to complete the rotation :math:`\Delta t_{\text{tot}}` is: + +.. math:: + \Delta t_{\text{tot}} = 2 \sqrt{ \frac{| \theta_{\text{ref}} - \theta_0 | }{\ddot{\theta}_{\text{max}}}} = t_f - t_0 + +Non-Smoothed Bang-Coast-Bang Profiler +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The second option to profile the spinning body rotation is a bang-coast-bang acceleration profile with an added coast +period between the acceleration segments where the acceleration is zero. Similar to the previous profiler, if the +spinning body reference angle is greater than the given initial angle, the maximum angular acceleration value is applied +positively for the specified ramp time ``coastOptionBangDuration`` to the first segment of the rotation and negatively +to the third segment of the rotation. The second segment of the rotation is the coast period. However, if the reference +angle is less than the initial spinning body angle, the acceleration is instead applied negatively during the first +segment of the rotation and positively during the third segment of the rotation. As a result of this acceleration +profile, the spinning body's hub-relative angle rate changes linearly with time and reaches a maximum in magnitude +at the end of the first segment and is constant during the coast segment. The angle rate returns to zero during the third +segment. The resulting spinning body angle for the rotation is parabolic during the first and third segments and linear +during the coast segment. + +To profile this spinning body motion, the spinning body's hub-relative scalar states :math:`\theta`, +:math:`\dot{\theta}`, and :math:`\ddot{\theta}` are prescribed as a function of time. During the first segment of the +rotation the states are: + +.. math:: + \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} + +.. math:: + \dot{\theta}(t) = \ddot{\theta} (t - t_0) + \dot{\theta}_0 + +.. math:: + \theta(t) = a (t - t_0)^2 + \theta_0 + +where + +.. math:: + a = \frac{ \theta(t_{b1}) - \theta_0}{2 (t_{b1} - t_0)^2} + +and :math:`\theta(t_{b1})` is the spinning body angle at the end of the first bang segment: + +.. math:: + \theta(t_{b1}) = \pm \frac{1}{2} \ddot{\theta}_{\text{max}} t_{\text{bang}}^2 + + \dot{\theta}_0 t_{\text{bang}} + \theta_0 + +.. important:: + Note the distinction between :math:`t_{b1}` and :math:`t_{\text{bang}}`. :math:`t_{\text{bang}}` is the time + duration of the acceleration segment configured by the user as the module variable ``coastOptionBangDuration``. + :math:`t_{b1}` is the simulation time at the end of the first acceleration segment. + :math:`t_{b1} = t_0 + t_{\text{bang}}` + +During the coast segment, the rotation states are: + +.. math:: + \ddot{\theta}(t) = 0 + +.. math:: + \dot{\theta}(t) = \dot{\theta}(t_{b1}) = \ddot{\theta}_{\text{max}} t_{\text{bang}} + \dot{\theta}_0 + +.. math:: + \theta(t) = \dot{\theta}(t_{b1}) (t - t_{b1}) + \theta(t_{b1}) + +During the third segment, the rotation states are + +.. math:: + \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} + +.. math:: + \dot{\theta}(t) = \ddot{\theta} (t - t_f) + \dot{\theta}_0 + +.. math:: + \theta(t) = b (t - t_f)^2 + \theta_{\text{ref}} + +where + +.. math:: + b = - \frac{ \theta_{\text{ref}} - \theta(t_c) }{(t_c - t_f)^2} + +Here :math:`\theta(t_c)` is the spinning body angle at the end of the coast segment: + +.. math:: + \theta(t_c) = \theta(t_{b1}) + \Delta \theta_{\text{coast}} + +and :math:`\Delta \theta_{\text{coast}}` is the angle traveled during the coast segment: + +.. math:: + \Delta \theta_{\text{coast}} = (\theta_{\text{ref}} - \theta_0) - 2 (\theta(t_{b1}) - \theta_0) + +:math:`t_c` is the simulation time at the end of the coast segment: + +.. math:: + t_c = t_{b1} + \frac{\Delta \theta_{\text{coast}}}{\dot{\theta}(t_{b1})} + +Using the given rotation axis ``rotHat_M``, the scalar states are then transformed to the spinning body +rotational states ``omega_FM_F``, ``omegaPrime_FM_F``, and ``sigma_FM``. The states are then written to the +:ref:`PrescribedRotationMsgPayload` module output message. + +Smoothed Bang-Bang Profiler +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The third option to profile the rotation is a smoothed bang-bang acceleration profile. This option is selected +by setting the module variable ``smoothingDuration`` to a nonzero value. This profiler uses cubic splines to construct +a continuous acceleration profiler across the entire rotation. Similar to the non-smoothed bang-bang profiler, +this option smooths the acceleration between the given maximum acceleration values. +To profile this motion, the spinning body's hub-relative scalar states :math:`\theta`, :math:`\dot{\theta}`, and +:math:`\ddot{\theta}` are prescribed as a function of time and the rotational motion is split into five different +segments. + +The first segment smooths the acceleration from zero to the user-specified maximum acceleration value in the given +time ``smoothingDuration``. If the given reference angle is greater than the given initial angle, the +acceleration is smoothed positively to the given maximum acceleration value. If the given reference angle is less +than the given initial angle, the acceleration is smoothed from zero to the negative maximum acceleration value. +During this phase, the scalar hub-relative states are: + +.. math:: + \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{3 (t - t_0)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_0)^3}{t_{\text{smooth}}^3} \right) + +.. math:: + \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_0)^3}{t_{\text{smooth}}^2} - \frac{(t - t_0)^4}{2 t_{\text{smooth}}^3} \right) + +.. math:: + \theta(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_0)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_0)^5}{10 t_{\text{smooth}}^3} \right) + \theta_0 + +The second segment is the first bang segment where the maximum acceleration value is applied either positively or +negatively as discussed previously. The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} + +.. math:: + \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} (t - t_{s1}) + \dot{\theta}(t_{s1}) + +.. math:: + \theta(t) = \pm \frac{\ddot{\theta}_{\text{max}} (t - t_{s1})^2}{2} + \dot{\theta}(t_{s1})(t - t_{s1}) + \theta(t_{s1}) + +where :math:`t_{s1}` is the time at the end of the first smoothing segment: + +.. math:: + t_{s1} = t_0 + t_{\text{smooth}} + +The third segment smooths the acceleration from the current maximum acceleration value to the opposite magnitude maximum +acceleration value. The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( 1 - \frac{3 (t - t_{b1})^2}{2 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^3}{2 t_{\text{smooth}}^3} \right) + +.. math:: + \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( (t - t_{b1}) - \frac{(t - t_{b1})^3}{2 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^4}{8 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_{b1}) + +.. math:: + \theta(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_{b1})^2}{2} - \frac{(t - t_{b1})^4}{8 t_{\text{smooth}}^2} + \frac{(t - t_{b1})^5}{40 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_{b1})(t - t_{b1}) + \theta(t_{b1}) + +where :math:`t_{b1}` is the time at the end of the first bang segment: + +.. math:: + t_{b1} = t_{s1} + t_{\text{bang}} + +The fourth segment is the second bang segment where the maximum acceleration value is applied either positively or +negatively as discussed previously. The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} + +.. math:: + \dot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} (t - t_{s2}) + \dot{\theta}(t_{s2}) + +.. math:: + \theta(t) = \mp \frac{\ddot{\theta}_{\text{max}} (t - t_{s2})^2}{2} + \dot{\theta}(t_{s2})(t - t_{s2}) + \theta(t_{s2}) + +where :math:`t_{s2}` is the time at the end of the second smoothing segment: + +.. math:: + t_{s2} = t_{b1} + t_{\text{smooth}} + +The fifth segment is the third and final smoothing segment where the acceleration returns to zero. The scalar +hub-relative states during this phase are: + +.. math:: + \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} \left ( -1 + \frac{3(t - t_{b2})^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_{b2})^3}{t_{\text{smooth}}^3} \right ) + +.. math:: + \dot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} \left ( -(t - t_{b2}) + \frac{(t - t_{b2})^3}{t_{\text{smooth}}^2} - \frac{(t - t_{b2})^4}{2 t_{\text{smooth}}^3} \right ) + \dot{\theta}(t_{b2}) + +.. math:: + \theta(t) = \mp \ddot{\theta}_{\text{max}} \left ( \frac{(t - t_{b2})^2}{2} + \frac{(t - t_{b2})^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_{b2})^5}{10 t_{\text{smooth}}^3} \right ) + \dot{\theta}(t_{b2})(t - t_{b2}) + \theta(t_{b2}) + +where :math:`t_{b2}` is the time at the end of the second bang segment: + +.. math:: + t_{b2} = t_{s2} + t_{\text{bang}} + +Smoothed Bang-Coast-Bang Profiler +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The fourth option to profile the rotation is a smoothed bang-coast-bang acceleration profile. This option is +selected by setting the module variables ``coastOptionBangDuration`` and ``smoothingDuration`` to nonzero values. +This profiler uses cubic splines to construct a continuous acceleration profiler across the entire rotation. +To profile this motion, the spinning body's hub-relative scalar states :math:`\theta`, :math:`\dot{\theta}`, and +:math:`\ddot{\theta}` are prescribed as a function of time and the rotational motion is split into seven different +segments. + +The first segment smooths the acceleration from zero to the user-specified maximum acceleration value in the given +time ``smoothingDuration``. If the given reference angle is greater than the given initial angle, the +acceleration is smoothed positively to the given maximum acceleration value. If the given reference angle is less +than the given initial angle, the acceleration is smoothed from zero to the negative maximum acceleration value. +During this phase, the scalar hub-relative states are: + +.. math:: + \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{3 (t - t_0)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_0)^3}{t_{\text{smooth}}^3} \right) + +.. math:: + \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_0)^3}{t_{\text{smooth}}^2} - \frac{(t - t_0)^4}{2 t_{\text{smooth}}^3} \right) + +.. math:: + \theta(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_0)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_0)^5}{10 t_{\text{smooth}}^3} \right) + \theta_0 + +The second segment is the first bang segment where the maximum acceleration value is applied either positively or +negatively as discussed previously. The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} + +.. math:: + \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} (t - t_{s1}) + \dot{\theta}(t_{s1}) + +.. math:: + \theta(t) = \pm \frac{\ddot{\theta}_{\text{max}} (t - t_{s1})^2}{2} + \dot{\theta}(t_{s1})(t - t_{s1}) + \theta(t_{s1}) + +where :math:`t_{s1}` is the time at the end of the first smoothing segment. + +The third segment prior to the coast phase smooths the acceleration from the current maximum acceleration value to zero. +The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( 1 - \frac{3 (t - t_{b1})^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_{b1})^3}{t_{\text{smooth}}^3} \right) + +.. math:: + \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left( (t - t_{b1}) - \frac{(t - t_{b1})^3}{t_{\text{smooth}}^2} - \frac{(t - t_{b1})^4}{2 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_{b1}) + +.. math:: + \theta(t) = \pm \ddot{\theta}_{\text{max}} \left( \frac{(t - t_{b1})^2}{2} - \frac{(t - t_{b1})^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_{b1})^5}{10 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_{b1})(t - t_{b1}) + \theta(t_{b1}) + +where :math:`t_{b1}` is the time at the end of the first bang segment. + +The fourth segment is the coast segment where the rotational states are: + +.. math:: + \ddot{\theta}(t) = 0 + +.. math:: + \dot{\theta}(t) = \dot{\theta}(t_{s2}) + +.. math:: + \theta(t) = \dot{\theta}(t_{s2}) (t - t_{s2}) + \theta(t_{s2}) + +where :math:`t_{s2}` is the time at the end of the second smoothing segment. + +The fifth segment smooths the acceleration from zero to the maximum acceleration value prior to the second bang segment. +The rotational states during this phase are: + +.. math:: + \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} \left( \frac{3 (t - t_c)^2}{t_{\text{smooth}}^2} - \frac{2 (t - t_c)^3}{t_{\text{smooth}}^3} \right) + +.. math:: + \dot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} \left( \frac{(t - t_c)^3}{t_{\text{smooth}}^2} - \frac{(t - t_c)^4}{2 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_c) + +.. math:: + \theta(t) = \mp \ddot{\theta}_{\text{max}} \left( \frac{(t - t_c)^4}{4 t_{\text{smooth}}^2} - \frac{(t - t_c)^5}{10 t_{\text{smooth}}^3} \right) + \dot{\theta}(t_c) (t - t_c) + \theta(t_c) + +where :math:`t_c` is the time at the end of the coast segment. + +The sixth segment is the second bang segment where the maximum acceleration value is applied either positively or +negatively as discussed previously. The scalar hub-relative states during this phase are: + +.. math:: + \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} + +.. math:: + \dot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} (t - t_{s3}) + \dot{\theta}(t_{s3}) + +.. math:: + \theta(t) = \mp \frac{\ddot{\theta}_{\text{max}} (t - t_{s3})^2}{2} + \dot{\theta}(t_{s3})(t - t_{s3}) + \theta(t_{s3}) + +where :math:`t_{s3}` is the time at the end of the third smoothing segment. + +The seventh segment is the fourth and final smoothing segment where the acceleration returns to zero. The scalar +hub-relative states during this phase are: + +.. math:: + \ddot{\theta}(t) = \mp \ddot{\theta}_{\text{max}} \left (\frac{3(t_f - t)^2}{t_{\text{smooth}}^2} - \frac{2 (t_f - t)^3}{t_{\text{smooth}}^3} \right ) + +.. math:: + \dot{\theta}(t) = \pm \ddot{\theta}_{\text{max}} \left (\frac{(t_f - t)^3}{t_{\text{smooth}}^2} - \frac{(t_f - t)^4}{2 t_{\text{smooth}}^3} \right ) + +.. math:: + \theta(t) = \mp \ddot{\theta}_{\text{max}} \left (\frac{(t_f - t)^4}{4 t_{\text{smooth}}^2} - \frac{(t_f - t)^5}{10 t_{\text{smooth}}^3} \right ) + \theta_{\text{ref}} + +where :math:`t_f` is the time at the end of the rotation: + +Module Testing +^^^^^^^^^^^^^^ +The unit test for this module ensures that the profiled 1 DOF rotation for a secondary rigid body relative to +the spacecraft hub is properly computed for several different simulation configurations. The unit test profiles +two successive rotations to ensure the module is correctly configured. The initial spinning body angle relative +to the spacecraft hub is varied, along with the two final reference angles and the maximum angular acceleration +for the rotation. + +The unit test also tests four different methods of profiling the rotation. Two profilers prescribe a pure +bang-bang or bang-coast-bang angular acceleration profile for the rotation. The bang-bang option results in +the fastest possible rotation; while the bang-coast-bang option includes a coast period with zero acceleration +between the acceleration segments. The other two profilers apply smoothing to the bang-bang and bang-coast-bang +acceleration profiles so that the spinning body hub-relative rates start and end at zero. + +To verify the module functionality, the final angle at the end of each rotation is checked to match the specified +reference angle. Additionally, for the smoothed profiler options, the numerical derivative of the profiled angles +and their rates is determined across the entire simulation. These numerical derivatives are checked with the module's +acceleration and rate profiles to ensure the profiled acceleration is correctly integrated in the module to obtain +the angles and their rates. + +User Guide +---------- +The general inputs to this module that must be set by the user are the spinning body rotation axis expressed as a +unit vector in mount frame components ``rotHat_M``, the initial spinning body angle relative to the hub-fixed +mount frame ``thetaInit``, the reference angle relative to the mount frame ``thetaRef``, and the maximum scalar angular +acceleration for the rotation ``thetaDDotMax``. The optional inputs ``coastOptionBangDuration`` and +``smoothingDuration`` can be set by the user to select the specific type of profiler that is desired. If these variables +are not set by the user, the module defaults to the non-smoothed bang-bang profiler. If only the variable +``coastOptionBangDuration`` is set to a nonzero value, the bang-coast-bang profiler is selected. If only the variable +``smoothingDuration`` is set to a nonzero value, the smoothed bang-bang profiler is selected. If both variables are +set to nonzero values, the smoothed bang-coast-bang profiler is selected. + +This section is to outline the steps needed to set up the prescribed rotational 1 DOF module in python using Xmera. + +#. Import the prescribedRotation1DOF class: + +.. code-block:: python + + from Xmera.simulation import prescribedRotation1DOF + +#. Create an instantiation of the module:: + + prescribedRot1DOF = prescribedRotation1DOF.PrescribedRotation1DOF() + +#. Define all of the configuration data associated with the module. For example, to configure the smoothed bang-coast-bang option: + +.. code-block:: python + + prescribedRot1DOF.modelTag = "prescribedRotation1DOF" + prescribedRot1DOF.setRotHat_M(np.array([0.0, 1.0, 0.0])) + prescribedRot1DOF.setThetaDDotMax(macros.D2R * 1.0) # [rad/s^2] + prescribedRot1DOF.setThetaInit(macros.D2R * 10.0) # [rad] + prescribedRot1DOF.setCoastOptionBangDuration(3.0) # [s] + prescribedRot1DOF.setSmoothingDuration(1.0) # [s] + +#. Connect a :ref:`HingedRigidBodyMsgPayload` message for the spinning body reference angle to the module. For example, the user can create a stand-alone message to specify the reference angle: + +.. code-block:: python + + hingedRigidBodyMessageData = messaging.HingedRigidBodyMsgPayload() + hingedRigidBodyMessageData.theta = macros.D2R * 90.0 # [rad] + hingedRigidBodyMessageData.thetaDot = 0.0 # [rad/s] + hingedRigidBodyMessage = messaging.HingedRigidBodyMsg().write(hingedRigidBodyMessageData) + +#. Subscribe the spinning body reference message to the prescribedRotation1DOF module input message:: + + prescribedRot1DOF.spinningBodyInMsg.subscribeTo(hingedRigidBodyMessage) + +#. Add the module to the task list:: + + unitTestSim.AddModelToTask(unitTaskName, prescribedRot1DOF) diff --git a/src/simulation/deviceInterface/singleAxisProfiler/singleAxisProfiler.rst b/src/simulation/deviceInterface/singleAxisProfiler/singleAxisProfiler.rst index ab1ebc363..f41357ed8 100644 --- a/src/simulation/deviceInterface/singleAxisProfiler/singleAxisProfiler.rst +++ b/src/simulation/deviceInterface/singleAxisProfiler/singleAxisProfiler.rst @@ -1,105 +1,109 @@ -Executive Summary ------------------ -This prescribed motion-specific module computes the hub-relative rotational states of a spinning body following -prescribed rotational one degree-of-freedom (DOF) motion about a single hub-fixed axis. The body frame of the spinning -body is designated by the frame :math:`\mathcal{F}`. The spinning body's states are profiled relative to a hub-fixed -frame :math:`\mathcal{M}`. The input message to this module is the :ref:`StepperMotorMsgPayload` message which provides -the scalar spinning body states relative to the hub ``theta``, ``thetaDot``, and ``thetaDDot``. Given these scalar -states together with the spinning body rotation axis specified by the user, the prescribed rotational states -``sigma_FM``, ``omega_FM_F``, and ``omegaPrime_FM_F`` are computed and output from the module using the -:ref:`PrescribedRotationMsgPayload` message. The only required input to this module that must be set by the user is -the spinning body rotation axis expressed as a unit vector in Mount frame components ``rotHat_M``. - -.. important:: - To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` - dynamics module. This ensures the spinning body's states are correctly incorporated into the spacecraft dynamics. - -Message Connection Descriptions -------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description -provides information on what the message is used for. - -.. list-table:: Module I/O Messages - :widths: 25 25 50 - :header-rows: 1 - - * - Msg Variable Name - - Msg Type - - Description - * - stepperMotorInMsg - - :ref:`StepperMotorMsgPayload` - - input msg with the stepper motor scalar states - * - prescribedRotationOutMsg - - :ref:`PrescribedRotationMsgPayload` - - output message with the prescribed spinning body rotational states - -Detailed Module Description ---------------------------- -To compute the spinning body attitude relative to the hub-fixed mount frame, the given axis of rotation and the current -stepper motor scalar angle are used in the following expression: - -.. math:: - \boldsymbol{\sigma}_{\mathcal{F}/\mathcal{M}} = \tan \left ( \frac{\theta}{4} \right ) \hat{\boldsymbol{s}} - -where :math:`\hat{\boldsymbol{s}}` is the given axis of rotation. - -The spinning body angular velocity relative to the mount frame is computed using the following expression: - -.. math:: - {}^{\mathcal{F}} \boldsymbol{\omega}_{\mathcal{F}/\mathcal{M}} = \dot{\theta} \ {}^{\mathcal{M}} \hat{\boldsymbol{s}} - -The spinning body angular acceleration relative to the mount frame is similarly computed: - -.. math:: - {}^{\mathcal{F}} \boldsymbol{\omega}^{'}_{\mathcal{F}/\mathcal{M}} = \ddot{\theta} \ {}^{\mathcal{M}} \hat{\boldsymbol{s}} - -The computed prescribed rotational states ``sigma_FM``, ``omega_FM_F``, and ``omegaPrime_FM_F`` are then written to the -:ref:`PrescribedRotationMsgPayload` module output message. - -Module Testing -^^^^^^^^^^^^^^ -The unit test for this module ensures that the single-axis hub-relative rotational scalar states ``theta``, -``thetaDot``, and ``thetaDDot`` are properly converted to prescribed hub-relative rotational states ``sigma_FM``, -``omega_FM_F``, and ``omegaPrime_FM_F``. The scalar states are varied in the test, along with a single angle -``rotAxis_MAngle`` that is used to vary the axis of rotation ``rotAxis_M`` associated with the given -scalar information. To verify the module, the final prescribed rotational states are logged from the module. The -final attitude is checked with the computed true attitude. The dot product between the given rotation axis and -the final angular velocity and angular acceleration is checked to match the given scalar angle rate and angle -acceleration. - -User Guide ----------- -The only required input to this module that must be set by the user is the spinning body rotation axis expressed -as a unit vector in Mount frame components ``rotHat_M``. This section outlines the steps needed to set up this -single axis profiler module in python using Xmera. - -#. Import the singleAxisProfiler class:: - - from Xmera.simulation import singleAxisProfiler - -#. Create an instantiation of the module:: - - singleAxisRotProfiler = singleAxisProfiler.SingleAxisProfiler() - -#. Define all of the configuration data associated with the module:: - - singleAxisRotProfiler.modelTag = "singleAxisProfiler" - singleAxisRotProfiler.setRotHat_M([1.0, 0.0, 0.0]) - -#. Connect the :ref:`StepperMotorMsgPayload` input message to the module that tracks the stepper motor states in time. For example, the user can create a stand-alone message to specify a non-rotating spinning body:: - - stepperMotorMessageData = messaging.StepperMotorMsgPayload() - stepperMotorMessageData.theta = 10.0 * np.pi / 180.0 # [rad] - stepperMotorMessageData.thetaDot = 0.0 * np.pi / 180.0 # [rad/s] - stepperMotorMessageData.thetaDDot = 0.0 * np.pi / 180.0 # [rad/s^2] - stepperMotorMessage = messaging.StepperMotorMsg().write(stepperMotorMessageData) - -#. Subscribe the singleAxisProfiler module input message to the stepper motor message:: - - singleAxisRotProfiler.stepperMotorInMsg.subscribeTo(stepperMotorMessage) - -#. Add the module to the task list:: - - unitTestSim.AddModelToTask(unitTaskName, singleAxisRotProfiler) +Executive Summary +----------------- +This prescribed motion-specific module computes the hub-relative rotational states of a spinning body following +prescribed rotational one degree-of-freedom (DOF) motion about a single hub-fixed axis. The body frame of the spinning +body is designated by the frame :math:`\mathcal{F}`. The spinning body's states are profiled relative to a hub-fixed +frame :math:`\mathcal{M}`. The input message to this module is the :ref:`StepperMotorMsgPayload` message which provides +the scalar spinning body states relative to the hub ``theta``, ``thetaDot``, and ``thetaDDot``. Given these scalar +states together with the spinning body rotation axis specified by the user, the prescribed rotational states +``sigma_FM``, ``omega_FM_F``, and ``omegaPrime_FM_F`` are computed and output from the module using the +:ref:`PrescribedRotationMsgPayload` message. The only required input to this module that must be set by the user is +the spinning body rotation axis expressed as a unit vector in Mount frame components ``rotHat_M``. + +.. important:: + To use this module for prescribed motion, it must be connected to the :ref:`PrescribedMotionStateEffector` + dynamics module. This ensures the spinning body's states are correctly incorporated into the spacecraft dynamics. + +Message Connection Descriptions +------------------------------- +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description +provides information on what the message is used for. + +.. list-table:: Module I/O Messages + :widths: 25 25 50 + :header-rows: 1 + + * - Msg Variable Name + - Msg Type + - Description + * - stepperMotorInMsg + - :ref:`StepperMotorMsgPayload` + - input msg with the stepper motor scalar states + * - prescribedRotationOutMsg + - :ref:`PrescribedRotationMsgPayload` + - output message with the prescribed spinning body rotational states + +Detailed Module Description +--------------------------- +To compute the spinning body attitude relative to the hub-fixed mount frame, the given axis of rotation and the current +stepper motor scalar angle are used in the following expression: + +.. math:: + \boldsymbol{\sigma}_{\mathcal{F}/\mathcal{M}} = \tan \left ( \frac{\theta}{4} \right ) \hat{\boldsymbol{s}} + +where :math:`\hat{\boldsymbol{s}}` is the given axis of rotation. + +The spinning body angular velocity relative to the mount frame is computed using the following expression: + +.. math:: + {}^{\mathcal{F}} \boldsymbol{\omega}_{\mathcal{F}/\mathcal{M}} = \dot{\theta} \ {}^{\mathcal{M}} \hat{\boldsymbol{s}} + +The spinning body angular acceleration relative to the mount frame is similarly computed: + +.. math:: + {}^{\mathcal{F}} \boldsymbol{\omega}^{'}_{\mathcal{F}/\mathcal{M}} = \ddot{\theta} \ {}^{\mathcal{M}} \hat{\boldsymbol{s}} + +The computed prescribed rotational states ``sigma_FM``, ``omega_FM_F``, and ``omegaPrime_FM_F`` are then written to the +:ref:`PrescribedRotationMsgPayload` module output message. + +Module Testing +^^^^^^^^^^^^^^ +The unit test for this module ensures that the single-axis hub-relative rotational scalar states ``theta``, +``thetaDot``, and ``thetaDDot`` are properly converted to prescribed hub-relative rotational states ``sigma_FM``, +``omega_FM_F``, and ``omegaPrime_FM_F``. The scalar states are varied in the test, along with a single angle +``rotAxis_MAngle`` that is used to vary the axis of rotation ``rotAxis_M`` associated with the given +scalar information. To verify the module, the final prescribed rotational states are logged from the module. The +final attitude is checked with the computed true attitude. The dot product between the given rotation axis and +the final angular velocity and angular acceleration is checked to match the given scalar angle rate and angle +acceleration. + +User Guide +---------- +The only required input to this module that must be set by the user is the spinning body rotation axis expressed +as a unit vector in Mount frame components ``rotHat_M``. This section outlines the steps needed to set up this +single axis profiler module in python using Xmera. + +#. Import the singleAxisProfiler class: + +.. code-block:: python + + from Xmera.simulation import singleAxisProfiler + +#. Create an instantiation of the module:: + + singleAxisRotProfiler = singleAxisProfiler.SingleAxisProfiler() + +#. Define all of the configuration data associated with the module:: + + singleAxisRotProfiler.modelTag = "singleAxisProfiler" + singleAxisRotProfiler.setRotHat_M([1.0, 0.0, 0.0]) + +#. Connect the :ref:`StepperMotorMsgPayload` input message to the module that tracks the stepper motor states in time. For example, the user can create a stand-alone message to specify a non-rotating spinning body: + +.. code-block:: python + + stepperMotorMessageData = messaging.StepperMotorMsgPayload() + stepperMotorMessageData.theta = 10.0 * np.pi / 180.0 # [rad] + stepperMotorMessageData.thetaDot = 0.0 * np.pi / 180.0 # [rad/s] + stepperMotorMessageData.thetaDDot = 0.0 * np.pi / 180.0 # [rad/s^2] + stepperMotorMessage = messaging.StepperMotorMsg().write(stepperMotorMessageData) + +#. Subscribe the singleAxisProfiler module input message to the stepper motor message:: + + singleAxisRotProfiler.stepperMotorInMsg.subscribeTo(stepperMotorMessage) + +#. Add the module to the task list:: + + unitTestSim.AddModelToTask(unitTaskName, singleAxisRotProfiler) diff --git a/src/simulation/dynamics/Thrusters/thrusterDynamicEffector/thrusterDynamicEffector.rst b/src/simulation/dynamics/Thrusters/thrusterDynamicEffector/thrusterDynamicEffector.rst index 5e18c4dba..32f491472 100644 --- a/src/simulation/dynamics/Thrusters/thrusterDynamicEffector/thrusterDynamicEffector.rst +++ b/src/simulation/dynamics/Thrusters/thrusterDynamicEffector/thrusterDynamicEffector.rst @@ -43,4 +43,4 @@ provides information on what this message is used for. - output message vector for thruster data .. note:: - The dynamic behaviour of this module is governed by the variables inside :ref:`THRTimePair`, which determine the on and off-ramp characteristics. The default behaviour is to not have on and off-ramps active. The ``cutoffFrequency`` variable inside :ref:`THRSimConfig` has no impact on this module and is instead supposed to be used to determine the dynamic behaviour within :ref:`thrusterStateEffector`. + The dynamic behaviour of this module is governed by the variables inside ``THRTimePair``, which determine the on and off-ramp characteristics. The default behaviour is to not have on and off-ramps active. The ``cutoffFrequency`` variable inside ``THRSimConfig`` has no impact on this module and is instead supposed to be used to determine the dynamic behaviour within :ref:`thrusterStateEffector`. diff --git a/src/simulation/dynamics/Thrusters/thrusterStateEffector/thrusterStateEffector.rst b/src/simulation/dynamics/Thrusters/thrusterStateEffector/thrusterStateEffector.rst index baba448fa..d0bb06108 100644 --- a/src/simulation/dynamics/Thrusters/thrusterStateEffector/thrusterStateEffector.rst +++ b/src/simulation/dynamics/Thrusters/thrusterStateEffector/thrusterStateEffector.rst @@ -110,7 +110,7 @@ Another limitation is that the :math:`I_{sp}` used is constant throughout the si .. note:: - The dynamic behaviour of this module is governed by the ``cutoffFrequency`` variable inside :ref:`THRSimConfig`. Its default value is equal to 10 rad/s. All variables related to on and off-ramps have no impact on this module and are instead supposed to be used to determine the dynamic behaviour within :ref:`thrusterDynamicEffector`. + The dynamic behaviour of this module is governed by the ``cutoffFrequency`` variable inside ``THRSimConfig``. Its default value is equal to 10 rad/s. All variables related to on and off-ramps have no impact on this module and are instead supposed to be used to determine the dynamic behaviour within :ref:`thrusterDynamicEffector`. @@ -123,7 +123,7 @@ Module Setup ~~~~~~~~~~~~ To use the thruster state effector module, the user first needs to create the thruster and populate it with the necessary information, such as thruster magnitude, minimum on time, etc. This can be done with the help -of the :ref:`simIncludeThruster` Xmera Python library. The code to create a generic thruster is shown below: +of the ``simIncludeThruster`` Xmera Python library. The code to create a generic thruster is shown below: .. code-block:: python diff --git a/src/simulation/dynamics/_GeneralModuleFiles/gravityEffector.rst b/src/simulation/dynamics/_GeneralModuleFiles/gravityEffector.rst index 55b53bec8..317cac9d3 100644 --- a/src/simulation/dynamics/_GeneralModuleFiles/gravityEffector.rst +++ b/src/simulation/dynamics/_GeneralModuleFiles/gravityEffector.rst @@ -50,11 +50,15 @@ If no message is connected, then the planet has zero position and orientation in User Guide ---------- -The user must provide a list of ``GravBodyData`` objects to the spacecraft using:: +The user must provide a list of ``GravBodyData`` objects to the spacecraft using: + +.. code-block:: python scObject.gravField.gravBodies = spacecraft.GravBodyVector(gravBodyList) -Each gravity body data object can be created using:: +Each gravity body data object can be created using: + +.. code-block:: python earth = gravityEffector.GravBodyData() earth.planetName = 'earth_planet_data' diff --git a/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.rst b/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.rst index 68651a93b..0c032d511 100644 --- a/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.rst +++ b/src/simulation/dynamics/facetSRPDynamicEffector/facetSRPDynamicEffector.rst @@ -1,210 +1,216 @@ -Executive Summary ------------------ -This dynamic effector module uses a faceted spacecraft model to calculate the force and torque acting on a spacecraft -due to solar radiation pressure (SRP). The force and torque are calculated about the spacecraft body frame origin -point :math:`B`. The module can be configured for either a static spacecraft or a spacecraft with any number of -articulating facets. For example, a spacecraft with two articulating solar arrays can be configured using 4 -articulating facets. The unit test for this module shows how to set up this particular configuration. - -Message Connection Descriptions -------------------------------- -The following table lists all the module input and output messages. -The module msg connection is set by the user from python. -The msg type contains a link to the message structure definition, while the description -provides information on what this message is used for. - -.. list-table:: Module I/O Messages - :widths: 25 25 50 - :header-rows: 1 - - * - Msg Variable Name - - Msg Type - - Description - * - sunInMsg - - :ref:`SpicePlanetStateMsgPayload` - - Input msg with the Sun state information - * - articulatedFacetDataInMsgs - - :ref:`HingedRigidBodyMsgPayload` - - (Optional) Input message with facet articulation angle information - -Detailed Module Description ---------------------------- - -Mathematical Modeling -^^^^^^^^^^^^^^^^^^^^^ -The spacecraft is represented as a collection of :math:`N` total facets with negligible thickness. Each facet is -characterized by an area :math:`A`, a unit vector normal to its surface :math:`\boldsymbol{\hat{n}}` expressed in -:math:`\mathcal{B}` frame components, a position vector from the spacecraft body frame origin point :math:`B` to the -facet center of pressure :math:`\boldsymbol{r}_{COP/B}` expressed in :math:`\mathcal{B}` frame components, -an optional unit vector expressed in :math:`\mathcal{B}` frame components representing the articulation axis of any -additional articulating facets, and three optical coefficients representing the interaction of impinging photons with -the facet surface. The fraction of specularly reflected, diffusely scattered, and absorbed photons are represented -using the coefficients :math:`\delta, \rho,` and :math:`\alpha`, respectively. - -For each articulating facet, the current facet normal vector is computed using the facet articulation axis -:math:`\boldsymbol{\hat{a}}` and the corresponding facet articulation angle :math:`\phi`. The facet articulation -angle is obtained from the ``articulatedFacetDataInMsgs`` input message data. The direction cosine matrix (DCM) -required to rotate the given facet normal vector through the current facet articulation angle is obtained using a -principal rotation vector (PRV) transformation where: - -.. math:: - [\mathcal{B}\mathcal{B}_0] = \text{PRV2C}(-\phi, \boldsymbol{\hat{a}}) - -and - -.. math:: - {}^\mathcal{B} \boldsymbol{\hat{n}} = [\mathcal{B}\mathcal{B}_0] {}^{\mathcal{B}_0} \boldsymbol{\hat{n}} - -Using the spacecraft facet information and spacecraft Sun-relative position vector -:math:`\boldsymbol{r}_{\text{sc} / \odot }`, the estimated SRP force acting on the spacecraft is calculated -by summing the SRP force contribution from all :math:`N` facets: - -.. math:: - \boldsymbol{F}_{\text{SRP}} = \sum_{i = 1}^{N} \boldsymbol{F}_{\text{SRP}_i} = -P(|\boldsymbol{r}_{\text{sc} / \odot }|) \sum_{i = 1}^{N} A_i \cos(\theta_i) \left [ (1 - \delta_i) \boldsymbol{\hat{s}} + 2 \left ( \frac{\rho_i}{3} + \delta_i \cos(\theta_i) \right ) \boldsymbol{\hat{n}}_{i}\right ] - -Where :math:`\theta` is defined as the incidence angle between each facet normal vector and the -Sun-direction vector, and :math:`P(|\boldsymbol{r}_{\text{sc}/ \odot\ }|)` is the pressure acting on the spacecraft -scaled by the spacecraft heliocentric distance. Because the Sun and spacecraft inertial positions are given in -inertial frame components, the current spacecraft attitude :math:`\sigma_{\mathcal{B} / \mathcal{N}}` is used -to determine the current DCM of the spacecraft body frame relative to the inertial frame, :math:`[\mathcal{BN}]`. -Note that all vector quantities must be expressed in the spacecraft body frame for the SRP force calculation. -:math:`\boldsymbol{\hat{s}}` is the unit direction vector pointing radially towards the Sun from the -spacecraft body frame origin point :math:`B`. This vector is found by subtracting the current spacecraft inertial -position from the Sun position given from the Sun Spice input message: - -.. math:: - {}^\mathcal{B} \boldsymbol{\hat{s}} = [\mathcal{BN}] ( {}^\mathcal{N} \boldsymbol{r}_{\odot / N} - {}^\mathcal{N} \boldsymbol{r}_{\text{sc} / N}) - -The total torque acting on the spacecraft about point :math:`B` due to SRP is calculated by summing the torque -contributions over all :math:`N` facets: - -.. math:: - \boldsymbol{L}_{\text{SRP},B} = \sum_{i = 1}^{N} \boldsymbol{L}_{{\text{SRP},B}_i} = \sum_{i = 1}^{N} \boldsymbol{r}_{{COP_i}/B} \times \boldsymbol{F}_{\text{SRP}_i} - -Module Testing -^^^^^^^^^^^^^^ -The unit test for this module ensures that the calculated SRP force and torque acting on the spacecraft about the -body-fixed point B is properly computed for either a static spacecraft or a spacecraft with any number of articulating -facets. The spacecraft geometry defined in the test consists of a cubic hub and two circular solar arrays. -Six static square facets represent the cubic hub and four articulated circular facets describe the articulating -solar arrays. To validate the module functionality, the final SRP force simulation value is checked with the -true value computed in python. - -User Guide ----------- -The following steps are required to set up the faceted SRP dynamic effector in python using Xmera. Be sure to include -the Sun as a gravitational body in the simulation to use this module. - -#. First import the facetSRPDynamicEffector class:: - - from Xmera.simulation import facetSRPDynamicEffector - -#. Next, create an instantiation of the SRP dynamic effector:: - - SRPEffector = facetSRPDynamicEffector.FacetSRPDynamicEffector() - SRPEffector.modelTag = "SRPEffector" - -#. The user is required to set the total number of spacecraft facets and the number of articulated facets. For example, if the user wants to create a spacecraft with 10 total facets, four of which articulate; the user would set these module variables to:: - - SRPEffector.numFacets = 10 - SRPEffector.numArticulatedFacets = 4 - -#. If the spacecraft contains articulated facets, a ``HingedRigidBodyMsgPayload`` articulation angle message must be configured for each articulated facet. An example using two constant stand-alone messages is provided below:: - - facetRotAngle1 = macros.D2R * 10.0 # [rad] - facetRotAngle2 = macros.D2R * -10.0 # [rad] - - facetRotAngle1MessageData = messaging.HingedRigidBodyMsgPayload() - facetRotAngle1MessageData.theta = facetRotAngle1 - facetRotAngle1MessageData.thetaDot = 0.0 - facetRotAngle1Message = messaging.HingedRigidBodyMsg().write(facetRotAngle1MessageData) - - facetRotAngle2MessageData = messaging.HingedRigidBodyMsgPayload() - facetRotAngle2MessageData.theta = facetRotAngle2 - facetRotAngle2MessageData.thetaDot = 0.0 - facetRotAngle2Message = messaging.HingedRigidBodyMsg().write(facetRotAngle2MessageData) - - -#. For articulating facets, the user must configure the module's optional ``articulatedFacetDataInMsgs`` input message by calling the ``addArticulatedFacet()`` method with each facet's ``HingedRigidBodyMsgPayload`` articulation angle input message:: - - srpEffector.addArticulatedFacet(facetRotAngle1Message) - srpEffector.addArticulatedFacet(facetRotAngle1Message) - srpEffector.addArticulatedFacet(facetRotAngle2Message) - srpEffector.addArticulatedFacet(facetRotAngle2Message) - -#. Next, define the spacecraft facet geometry information that is contained in the module's ``FacetedSRPSpacecraftGeometryData`` structure:: - - # Define facet areas - area1 = 1.5 * 1.5 - area2 = np.pi * (0.5 * 7.5) * (0.5 * 7.5) - facetAreas = [area1, area1, area1, area1, area1, area1, area2, area2, area2, area2] - - # Define the facet normal vectors in B frame components - facetNormals_B = [np.array([1.0, 0.0, 0.0]), - np.array([0.0, 1.0, 0.0]), - np.array([-1.0, 0.0, 0.0]), - np.array([0.0, -1.0, 0.0]), - np.array([0.0, 0.0, 1.0]), - np.array([0.0, 0.0, -1.0]), - np.array([0.0, 1.0, 0.0]), - np.array([0.0, -1.0, 0.0]), - np.array([0.0, 1.0, 0.0]), - np.array([0.0, -1.0, 0.0])] - - # Define facet center of pressure locations relative to point B - locationsPntB_B = [np.array([0.75, 0.0, 0.0]), - np.array([0.0, 0.75, 0.0]), - np.array([-0.75, 0.0, 0.0]), - np.array([0.0, -0.75, 0.0]), - np.array([0.0, 0.0, 0.75]), - np.array([0.0, 0.0, -0.75]), - np.array([4.5, 0.0, 0.75]), - np.array([4.5, 0.0, 0.75]), - np.array([-4.5, 0.0, 0.75]), - np.array([-4.5, 0.0, 0.75])] - - # Define facet articulation axes in B frame components - rotAxes_B = [np.array([0.0, 0.0, 0.0]), - np.array([0.0, 0.0, 0.0]), - np.array([0.0, 0.0, 0.0]), - np.array([0.0, 0.0, 0.0]), - np.array([0.0, 0.0, 0.0]), - np.array([0.0, 0.0, 0.0]), - np.array([1.0, 0.0, 0.0]), - np.array([1.0, 0.0, 0.0]), - np.array([-1.0, 0.0, 0.0]), - np.array([-1.0, 0.0, 0.0])] - - # Define facet optical coefficients - specCoeff = np.array([0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9]) - diffCoeff = np.array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]) - -.. important:: - Note that in order to use this module, the facet articulation axes must always be configured regardless of whether - articulated facets are considered. For all static facets, the articulation axes must be set to zero. Ensure that the - specified number of articulated facets matches the number of nonzero articulation axes. - -.. important:: - The module requires the articulated facet data to be added at the end of the facet data vectors. - -#. Populate the module's ``FacetedSRPSpacecraftGeometryData`` structure with the spacecraft facet information using the ``addFacet()`` method:: - - for i in range(numFacets)): - SRPEffector.addFacet(facetAreas[i], specCoeff[i], diffCoeff[i], facetNormals_B[i], locationsPntB_B[i], rotAxes_B[i]) - -#. Connect the Sun's ephemeris message to the SRP module:: - - SRPEffector.sunInMsg.subscribeTo(sunMsg) - -#. Add the SRP dynamic effector to the spacecraft:: - - scObject.addDynamicEffector(SRPEffector) - - See :ref:`spacecraft` documentation on how to set up a spacecraft object. - -#. Finally, add the SRP effector module to the task list:: - - unitTestSim.AddModelToTask(unitTaskName, SRPEffector) - -.. note:: - See the example script :ref:`scenarioSepMomentumManagement`, which illustrates how to set up a spacecraft with articulated panels for SRP calculation. +Executive Summary +----------------- +This dynamic effector module uses a faceted spacecraft model to calculate the force and torque acting on a spacecraft +due to solar radiation pressure (SRP). The force and torque are calculated about the spacecraft body frame origin +point :math:`B`. The module can be configured for either a static spacecraft or a spacecraft with any number of +articulating facets. For example, a spacecraft with two articulating solar arrays can be configured using 4 +articulating facets. The unit test for this module shows how to set up this particular configuration. + +Message Connection Descriptions +------------------------------- +The following table lists all the module input and output messages. +The module msg connection is set by the user from python. +The msg type contains a link to the message structure definition, while the description +provides information on what this message is used for. + +.. list-table:: Module I/O Messages + :widths: 25 25 50 + :header-rows: 1 + + * - Msg Variable Name + - Msg Type + - Description + * - sunInMsg + - :ref:`SpicePlanetStateMsgPayload` + - Input msg with the Sun state information + * - articulatedFacetDataInMsgs + - :ref:`HingedRigidBodyMsgPayload` + - (Optional) Input message with facet articulation angle information + +Detailed Module Description +--------------------------- + +Mathematical Modeling +^^^^^^^^^^^^^^^^^^^^^ +The spacecraft is represented as a collection of :math:`N` total facets with negligible thickness. Each facet is +characterized by an area :math:`A`, a unit vector normal to its surface :math:`\boldsymbol{\hat{n}}` expressed in +:math:`\mathcal{B}` frame components, a position vector from the spacecraft body frame origin point :math:`B` to the +facet center of pressure :math:`\boldsymbol{r}_{COP/B}` expressed in :math:`\mathcal{B}` frame components, +an optional unit vector expressed in :math:`\mathcal{B}` frame components representing the articulation axis of any +additional articulating facets, and three optical coefficients representing the interaction of impinging photons with +the facet surface. The fraction of specularly reflected, diffusely scattered, and absorbed photons are represented +using the coefficients :math:`\delta, \rho,` and :math:`\alpha`, respectively. + +For each articulating facet, the current facet normal vector is computed using the facet articulation axis +:math:`\boldsymbol{\hat{a}}` and the corresponding facet articulation angle :math:`\phi`. The facet articulation +angle is obtained from the ``articulatedFacetDataInMsgs`` input message data. The direction cosine matrix (DCM) +required to rotate the given facet normal vector through the current facet articulation angle is obtained using a +principal rotation vector (PRV) transformation where: + +.. math:: + [\mathcal{B}\mathcal{B}_0] = \text{PRV2C}(-\phi, \boldsymbol{\hat{a}}) + +and + +.. math:: + {}^\mathcal{B} \boldsymbol{\hat{n}} = [\mathcal{B}\mathcal{B}_0] {}^{\mathcal{B}_0} \boldsymbol{\hat{n}} + +Using the spacecraft facet information and spacecraft Sun-relative position vector +:math:`\boldsymbol{r}_{\text{sc} / \odot }`, the estimated SRP force acting on the spacecraft is calculated +by summing the SRP force contribution from all :math:`N` facets: + +.. math:: + \boldsymbol{F}_{\text{SRP}} = \sum_{i = 1}^{N} \boldsymbol{F}_{\text{SRP}_i} = -P(|\boldsymbol{r}_{\text{sc} / \odot }|) \sum_{i = 1}^{N} A_i \cos(\theta_i) \left [ (1 - \delta_i) \boldsymbol{\hat{s}} + 2 \left ( \frac{\rho_i}{3} + \delta_i \cos(\theta_i) \right ) \boldsymbol{\hat{n}}_{i}\right ] + +Where :math:`\theta` is defined as the incidence angle between each facet normal vector and the +Sun-direction vector, and :math:`P(|\boldsymbol{r}_{\text{sc}/ \odot\ }|)` is the pressure acting on the spacecraft +scaled by the spacecraft heliocentric distance. Because the Sun and spacecraft inertial positions are given in +inertial frame components, the current spacecraft attitude :math:`\sigma_{\mathcal{B} / \mathcal{N}}` is used +to determine the current DCM of the spacecraft body frame relative to the inertial frame, :math:`[\mathcal{BN}]`. +Note that all vector quantities must be expressed in the spacecraft body frame for the SRP force calculation. +:math:`\boldsymbol{\hat{s}}` is the unit direction vector pointing radially towards the Sun from the +spacecraft body frame origin point :math:`B`. This vector is found by subtracting the current spacecraft inertial +position from the Sun position given from the Sun Spice input message: + +.. math:: + {}^\mathcal{B} \boldsymbol{\hat{s}} = [\mathcal{BN}] ( {}^\mathcal{N} \boldsymbol{r}_{\odot / N} - {}^\mathcal{N} \boldsymbol{r}_{\text{sc} / N}) + +The total torque acting on the spacecraft about point :math:`B` due to SRP is calculated by summing the torque +contributions over all :math:`N` facets: + +.. math:: + \boldsymbol{L}_{\text{SRP},B} = \sum_{i = 1}^{N} \boldsymbol{L}_{{\text{SRP},B}_i} = \sum_{i = 1}^{N} \boldsymbol{r}_{{COP_i}/B} \times \boldsymbol{F}_{\text{SRP}_i} + +Module Testing +^^^^^^^^^^^^^^ +The unit test for this module ensures that the calculated SRP force and torque acting on the spacecraft about the +body-fixed point B is properly computed for either a static spacecraft or a spacecraft with any number of articulating +facets. The spacecraft geometry defined in the test consists of a cubic hub and two circular solar arrays. +Six static square facets represent the cubic hub and four articulated circular facets describe the articulating +solar arrays. To validate the module functionality, the final SRP force simulation value is checked with the +true value computed in python. + +User Guide +---------- +The following steps are required to set up the faceted SRP dynamic effector in python using Xmera. Be sure to include +the Sun as a gravitational body in the simulation to use this module. + +#. First import the facetSRPDynamicEffector class: + +.. code-block:: python + + from Xmera.simulation import facetSRPDynamicEffector + +#. Next, create an instantiation of the SRP dynamic effector:: + + SRPEffector = facetSRPDynamicEffector.FacetSRPDynamicEffector() + SRPEffector.modelTag = "SRPEffector" + +#. The user is required to set the total number of spacecraft facets and the number of articulated facets. For example, if the user wants to create a spacecraft with 10 total facets, four of which articulate; the user would set these module variables to:: + + SRPEffector.numFacets = 10 + SRPEffector.numArticulatedFacets = 4 + +#. If the spacecraft contains articulated facets, a ``HingedRigidBodyMsgPayload`` articulation angle message must be configured for each articulated facet. An example using two constant stand-alone messages is provided below: + +.. code-block:: python + + facetRotAngle1 = macros.D2R * 10.0 # [rad] + facetRotAngle2 = macros.D2R * -10.0 # [rad] + + facetRotAngle1MessageData = messaging.HingedRigidBodyMsgPayload() + facetRotAngle1MessageData.theta = facetRotAngle1 + facetRotAngle1MessageData.thetaDot = 0.0 + facetRotAngle1Message = messaging.HingedRigidBodyMsg().write(facetRotAngle1MessageData) + + facetRotAngle2MessageData = messaging.HingedRigidBodyMsgPayload() + facetRotAngle2MessageData.theta = facetRotAngle2 + facetRotAngle2MessageData.thetaDot = 0.0 + facetRotAngle2Message = messaging.HingedRigidBodyMsg().write(facetRotAngle2MessageData) + + +#. For articulating facets, the user must configure the module's optional ``articulatedFacetDataInMsgs`` input message by calling the ``addArticulatedFacet()`` method with each facet's ``HingedRigidBodyMsgPayload`` articulation angle input message:: + + srpEffector.addArticulatedFacet(facetRotAngle1Message) + srpEffector.addArticulatedFacet(facetRotAngle1Message) + srpEffector.addArticulatedFacet(facetRotAngle2Message) + srpEffector.addArticulatedFacet(facetRotAngle2Message) + +#. Next, define the spacecraft facet geometry information that is contained in the module's ``FacetedSRPSpacecraftGeometryData`` structure: + +.. code-block:: python + + # Define facet areas + area1 = 1.5 * 1.5 + area2 = np.pi * (0.5 * 7.5) * (0.5 * 7.5) + facetAreas = [area1, area1, area1, area1, area1, area1, area2, area2, area2, area2] + + # Define the facet normal vectors in B frame components + facetNormals_B = [np.array([1.0, 0.0, 0.0]), + np.array([0.0, 1.0, 0.0]), + np.array([-1.0, 0.0, 0.0]), + np.array([0.0, -1.0, 0.0]), + np.array([0.0, 0.0, 1.0]), + np.array([0.0, 0.0, -1.0]), + np.array([0.0, 1.0, 0.0]), + np.array([0.0, -1.0, 0.0]), + np.array([0.0, 1.0, 0.0]), + np.array([0.0, -1.0, 0.0])] + + # Define facet center of pressure locations relative to point B + locationsPntB_B = [np.array([0.75, 0.0, 0.0]), + np.array([0.0, 0.75, 0.0]), + np.array([-0.75, 0.0, 0.0]), + np.array([0.0, -0.75, 0.0]), + np.array([0.0, 0.0, 0.75]), + np.array([0.0, 0.0, -0.75]), + np.array([4.5, 0.0, 0.75]), + np.array([4.5, 0.0, 0.75]), + np.array([-4.5, 0.0, 0.75]), + np.array([-4.5, 0.0, 0.75])] + + # Define facet articulation axes in B frame components + rotAxes_B = [np.array([0.0, 0.0, 0.0]), + np.array([0.0, 0.0, 0.0]), + np.array([0.0, 0.0, 0.0]), + np.array([0.0, 0.0, 0.0]), + np.array([0.0, 0.0, 0.0]), + np.array([0.0, 0.0, 0.0]), + np.array([1.0, 0.0, 0.0]), + np.array([1.0, 0.0, 0.0]), + np.array([-1.0, 0.0, 0.0]), + np.array([-1.0, 0.0, 0.0])] + + # Define facet optical coefficients + specCoeff = np.array([0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9]) + diffCoeff = np.array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]) + +.. important:: + Note that in order to use this module, the facet articulation axes must always be configured regardless of whether + articulated facets are considered. For all static facets, the articulation axes must be set to zero. Ensure that the + specified number of articulated facets matches the number of nonzero articulation axes. + +.. important:: + The module requires the articulated facet data to be added at the end of the facet data vectors. + +#. Populate the module's ``FacetedSRPSpacecraftGeometryData`` structure with the spacecraft facet information using the ``addFacet()`` method:: + + for i in range(numFacets)): + SRPEffector.addFacet(facetAreas[i], specCoeff[i], diffCoeff[i], facetNormals_B[i], locationsPntB_B[i], rotAxes_B[i]) + +#. Connect the Sun's ephemeris message to the SRP module:: + + SRPEffector.sunInMsg.subscribeTo(sunMsg) + +#. Add the SRP dynamic effector to the spacecraft:: + + scObject.addDynamicEffector(SRPEffector) + + See :ref:`spacecraft` documentation on how to set up a spacecraft object. + +#. Finally, add the SRP effector module to the task list:: + + unitTestSim.AddModelToTask(unitTaskName, SRPEffector) + +.. note:: + See the example script :ref:`scenarioSepMomentumManagement`, which illustrates how to set up a spacecraft with articulated panels for SRP calculation. diff --git a/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.rst b/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.rst index 42dcfb255..2fc690290 100644 --- a/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.rst +++ b/src/simulation/dynamics/linearTranslationalBodies/linearTranslationBodiesOneDOF/linearTranslationOneDOFStateEffector.rst @@ -51,7 +51,9 @@ User Guide ---------- This section is to outline the steps needed to setup a Translating Body State Effector in Python using Xmera. -#. Import the linearTranslatingBodyOneDOFStateEffector class:: +#. Import the linearTranslatingBodyOneDOFStateEffector class: + +.. code-block:: python from Xmera.simulation import linearTranslatingBodyOneDOFStateEffector @@ -87,7 +89,9 @@ This section is to outline the steps needed to setup a Translating Body State Ef translatingBody.nameOfThetaState = "translatingBodyRho" translatingBody.nameOfThetaDotState = "translatingBodyRhoDot" -#. (Optional) Connect a command force message:: +#. (Optional) Connect a command force message: + +.. code-block:: python cmdArray = messaging.ArrayMotorForceMsgPayload() cmdArray.motorForce = [cmdForce] # [Nm] diff --git a/src/simulation/dynamics/prescribedMotion/prescribedMotionStateEffector.rst b/src/simulation/dynamics/prescribedMotion/prescribedMotionStateEffector.rst index c66370031..e5e223722 100644 --- a/src/simulation/dynamics/prescribedMotion/prescribedMotionStateEffector.rst +++ b/src/simulation/dynamics/prescribedMotion/prescribedMotionStateEffector.rst @@ -1,130 +1,134 @@ - -Executive Summary ------------------ -The prescribed motion class is an instantiation of the state effector abstract class. This module describes the dynamics -of a rigid sub-component whose three-dimensional motion can be kinematically prescribed relative to a central rigid -spacecraft hub whose body frame is denoted as the frame :math:`\mathcal{B}`. The body frame for the prescribed body is -designated by the frame :math:`\mathcal{F}`. The prescribed body must be commanded to translate and rotate in -three-dimensional space relative to a hub-fixed interface designated as the mount frame :math:`\mathcal{M}`. -Accordingly, the prescribed states for the sub-component are written with respect to the -mount frame :math:`\mathcal{M}`: -``r_FM_M``, ``rPrime_FM_M``, ``rPrimePrime_FM_M``, ``omega_FM_F``, ``omegaPrime_FM_F``, and ``sigma_FM``. - -The states of the prescribed body are not defined or integrated in this module. No equations of motion exist that need -to be integrated for this type of state effector. Therefore, separate kinematic profiler modules must -be connected to this module's prescribed motion :ref:`PrescribedTranslationMsgPayload` and -:ref:`PrescribedRotationMsgPayload` input messages to profile the prescribed sub-component's states as a function of -time. These message connections are required to provide the sub-component's states to this dynamics module. -Note that either a single profiler can be connected to both of these input messages, or two separate profiler modules -can be used; where one profiles the sub-component's translational states and the other profiles the sub-component's -rotational states. See the example script :ref:`scenarioDeployingSolarArrays` for more information about how to set up -hub-relative multi-body prescribed motion using this state effector module and the associated kinematic profiler modules. - -Message Connection Descriptions -------------------------------- -The following table lists all the module input and output messages. The module msg variable name is set by the -user from python. The msg type contains a link to the message structure definition, while the description -provides information on what this message is used for. - - -.. list-table:: Module I/O Messages - :widths: 25 25 50 - :header-rows: 1 - - * - Msg Variable Name - - Msg Type - - Description - * - prescribedTranslationInMsg - - :ref:`PrescribedTranslationMsgPayload` - - Input message for the effector's translational prescribed states - * - prescribedRotationInMsg - - :ref:`PrescribedRotationMsgPayload` - - Input message for the effector's rotational prescribed states - * - prescribedTranslationOutMsg - - :ref:`PrescribedTranslationMsgPayload` - - Output message for the effector's translational prescribed states - * - prescribedRotationOutMsg - - :ref:`PrescribedRotationMsgPayload` - - Output message for the effector's rotational prescribed states - * - prescribedMotionConfigLogOutMsg - - :ref:`SCStatesMsgPayload` - - Output message containing the effector's inertial position and attitude states - - -Detailed Module Description ---------------------------- - -Mathematical Modeling -^^^^^^^^^^^^^^^^^^^^^ -See Kiner et al.'s paper: `Spacecraft Simulation Software Implementation of General Prescribed Motion Dynamics of Two Connected Rigid Bodies `__ -for a detailed description of the derived prescribed motion spacecraft dynamics. - -The translational equations of motion are: - -.. math:: - m_{\text{sc}} \left [ \ddot{\boldsymbol{r}}_{B/N} + \boldsymbol{c}^{''} + 2 \left ( \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \times \boldsymbol{c}^{'} \right ) + \left ( \dot{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}} \times \boldsymbol{c} \right ) + \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \times \left ( \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \times \boldsymbol{c} \right ) \right ] = \sum \boldsymbol{F}_{\text{ext}} - -The rotational equations of motion are: - -.. math:: - m_{\text{sc}} [\tilde{\boldsymbol{c}}] \ddot{\boldsymbol{r}}_{B/N} + [I_{\text{sc},B}] \dot{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}} = \boldsymbol{L}_B - m_{\text{P}} [\tilde{\boldsymbol{r}}_{F_c/B}] \boldsymbol{r}^{''}_{F_c/B} - \left ( [I^{'}_{\text{sc},B}] + [\tilde{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}}][I_{\text{sc},B}] \right ) \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \\ - \left ( [I^{'}_{\text{P},F_c}] + [\tilde{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}}] [I_{\text{P},F_c}] \right ) \boldsymbol{\omega}_{\mathcal{F}/\mathcal{B}} \ - \ [I_{\text{P},F_c}] \boldsymbol{\omega}^{'}_{\mathcal{F}/\mathcal{B}} \ - \ m_{\text{P}} [\tilde{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}}] [\tilde{\boldsymbol{r}}_{F_c/B}] \boldsymbol{r}^{'}_{F_c/B} - -Module Testing -^^^^^^^^^^^^^^ - -There are two integrated unit test scripts written for this module. - -The first integrated test uses the :ref:`prescribedRotation1DOF` kinematic profiler module to prescribe a -1-degree-of-freedom (1-DOF) rotation for the prescribed state effector relative to the spacecraft hub. -The second integrated test uses the :ref:`prescribedLinearTranslation` kinematic profiler module to prescribe linear -translational motion for the prescribed state effector relative to the spacecraft hub. - -Both integrated test scripts verify the prescribed motion state effector dynamics by checking to ensure that the -orbital angular momentum, orbital energy, and spacecraft rotational angular momentum quantities are reasonably -conserved. - - -User Guide ----------- -This section outlines the steps needed to set up the prescribed motion state effector module in python using Xmera. - -#. Import the prescribedMotionStateEffector class:: - - from Xmera.simulation import prescribedMotionStateEffector - -#. Create the prescribed motion state effector:: - - prescribed_motion_body = prescribedMotionStateEffector.PrescribedMotionStateEffector() - -#. Define the prescribed motion state effector module parameters:: - - prescribed_motion_body.setMass(10.0) # [kg] - prescribed_motion_body.setIPntFc_F([[50.0, 0.0, 0.0], [0.0, 50.0, 0.0], [0.0, 0.0, 50.0]]) # [kg-m^2] - prescribed_motion_body.setR_MB_B([1.0, 0.0, 0.0]) # [m] - prescribed_motion_body.setR_FcF_F([0.1, 0.0, -0.5]) # [m] - prescribed_motion_body.setR_FM_M([0.0, 0.0, 0.0]) # [m] - prescribed_motion_body.setRPrime_FM_M([0.0, 0.0, 0.0]) # [m/s] - prescribed_motion_body.setRPrimePrime_FM_M([0.0, 0.0, 0.0]) # [m/s^2] - prescribed_motion_body.setOmega_FM_F([0.0, 0.0, 0.0]) # [rad/s] - prescribed_motion_body.setOmegaPrime_FM_F([0.0, 0.0, 0.0]) # [rad/s^2] - prescribed_motion_body.setSigma_FM([0.0, 0.0, 0.0]) - prescribed_motion_body.setOmega_MB_M([0.0, 0.0, 0.0]) # [rad/s] - prescribed_motion_body.setOmegaPrime_MB_B([0.0, 0.0, 0.0]) # [rad/s^2] - prescribed_motion_body.setSigma_MB([0.0, 0.0, 0.0]) - prescribed_motion_body.modelTag = "prescribedMotionBody" - -Note that if these parameters are not set by the user, the vector quantities are set to zero and the matrix and scalar -quantities are set to identity by default. - -#. Add the prescribed state effector to the spacecraft object:: - - scObject.addStateEffector(prescribed_motion_body) - -#. Add the module to the task list:: - - unitTestSim.AddModelToTask(unitTaskName, prescribed_motion_body) - -Make sure to connect the required messages for this module using the kinematic profiler modules if the prescribed motion -body is to be actuated relative to the spacecraft hub. See the example script :ref:`scenarioDeployingSolarArrays` for -more information about how to set up hub-relative multi-body prescribed motion using this state effector module and the -associated kinematic profiler modules. + +Executive Summary +----------------- +The prescribed motion class is an instantiation of the state effector abstract class. This module describes the dynamics +of a rigid sub-component whose three-dimensional motion can be kinematically prescribed relative to a central rigid +spacecraft hub whose body frame is denoted as the frame :math:`\mathcal{B}`. The body frame for the prescribed body is +designated by the frame :math:`\mathcal{F}`. The prescribed body must be commanded to translate and rotate in +three-dimensional space relative to a hub-fixed interface designated as the mount frame :math:`\mathcal{M}`. +Accordingly, the prescribed states for the sub-component are written with respect to the +mount frame :math:`\mathcal{M}`: +``r_FM_M``, ``rPrime_FM_M``, ``rPrimePrime_FM_M``, ``omega_FM_F``, ``omegaPrime_FM_F``, and ``sigma_FM``. + +The states of the prescribed body are not defined or integrated in this module. No equations of motion exist that need +to be integrated for this type of state effector. Therefore, separate kinematic profiler modules must +be connected to this module's prescribed motion :ref:`PrescribedTranslationMsgPayload` and +:ref:`PrescribedRotationMsgPayload` input messages to profile the prescribed sub-component's states as a function of +time. These message connections are required to provide the sub-component's states to this dynamics module. +Note that either a single profiler can be connected to both of these input messages, or two separate profiler modules +can be used; where one profiles the sub-component's translational states and the other profiles the sub-component's +rotational states. See the example script :ref:`scenarioDeployingSolarArrays` for more information about how to set up +hub-relative multi-body prescribed motion using this state effector module and the associated kinematic profiler modules. + +Message Connection Descriptions +------------------------------- +The following table lists all the module input and output messages. The module msg variable name is set by the +user from python. The msg type contains a link to the message structure definition, while the description +provides information on what this message is used for. + + +.. list-table:: Module I/O Messages + :widths: 25 25 50 + :header-rows: 1 + + * - Msg Variable Name + - Msg Type + - Description + * - prescribedTranslationInMsg + - :ref:`PrescribedTranslationMsgPayload` + - Input message for the effector's translational prescribed states + * - prescribedRotationInMsg + - :ref:`PrescribedRotationMsgPayload` + - Input message for the effector's rotational prescribed states + * - prescribedTranslationOutMsg + - :ref:`PrescribedTranslationMsgPayload` + - Output message for the effector's translational prescribed states + * - prescribedRotationOutMsg + - :ref:`PrescribedRotationMsgPayload` + - Output message for the effector's rotational prescribed states + * - prescribedMotionConfigLogOutMsg + - :ref:`SCStatesMsgPayload` + - Output message containing the effector's inertial position and attitude states + + +Detailed Module Description +--------------------------- + +Mathematical Modeling +^^^^^^^^^^^^^^^^^^^^^ +See Kiner et al.'s paper: `Spacecraft Simulation Software Implementation of General Prescribed Motion Dynamics of Two Connected Rigid Bodies `__ +for a detailed description of the derived prescribed motion spacecraft dynamics. + +The translational equations of motion are: + +.. math:: + m_{\text{sc}} \left [ \ddot{\boldsymbol{r}}_{B/N} + \boldsymbol{c}^{''} + 2 \left ( \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \times \boldsymbol{c}^{'} \right ) + \left ( \dot{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}} \times \boldsymbol{c} \right ) + \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \times \left ( \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \times \boldsymbol{c} \right ) \right ] = \sum \boldsymbol{F}_{\text{ext}} + +The rotational equations of motion are: + +.. math:: + m_{\text{sc}} [\tilde{\boldsymbol{c}}] \ddot{\boldsymbol{r}}_{B/N} + [I_{\text{sc},B}] \dot{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}} = \boldsymbol{L}_B - m_{\text{P}} [\tilde{\boldsymbol{r}}_{F_c/B}] \boldsymbol{r}^{''}_{F_c/B} - \left ( [I^{'}_{\text{sc},B}] + [\tilde{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}}][I_{\text{sc},B}] \right ) \boldsymbol{\omega}_{\mathcal{B}/\mathcal{N}} \\ - \left ( [I^{'}_{\text{P},F_c}] + [\tilde{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}}] [I_{\text{P},F_c}] \right ) \boldsymbol{\omega}_{\mathcal{F}/\mathcal{B}} \ - \ [I_{\text{P},F_c}] \boldsymbol{\omega}^{'}_{\mathcal{F}/\mathcal{B}} \ - \ m_{\text{P}} [\tilde{\boldsymbol{\omega}}_{\mathcal{B}/\mathcal{N}}] [\tilde{\boldsymbol{r}}_{F_c/B}] \boldsymbol{r}^{'}_{F_c/B} + +Module Testing +^^^^^^^^^^^^^^ + +There are two integrated unit test scripts written for this module. + +The first integrated test uses the :ref:`prescribedRotation1DOF` kinematic profiler module to prescribe a +1-degree-of-freedom (1-DOF) rotation for the prescribed state effector relative to the spacecraft hub. +The second integrated test uses the :ref:`prescribedLinearTranslation` kinematic profiler module to prescribe linear +translational motion for the prescribed state effector relative to the spacecraft hub. + +Both integrated test scripts verify the prescribed motion state effector dynamics by checking to ensure that the +orbital angular momentum, orbital energy, and spacecraft rotational angular momentum quantities are reasonably +conserved. + + +User Guide +---------- +This section outlines the steps needed to set up the prescribed motion state effector module in python using Xmera. + +#. Import the prescribedMotionStateEffector class: + +.. code-block:: python + + from Xmera.simulation import prescribedMotionStateEffector + +#. Create the prescribed motion state effector:: + + prescribed_motion_body = prescribedMotionStateEffector.PrescribedMotionStateEffector() + +#. Define the prescribed motion state effector module parameters: + +.. code-block:: python + + prescribed_motion_body.setMass(10.0) # [kg] + prescribed_motion_body.setIPntFc_F([[50.0, 0.0, 0.0], [0.0, 50.0, 0.0], [0.0, 0.0, 50.0]]) # [kg-m^2] + prescribed_motion_body.setR_MB_B([1.0, 0.0, 0.0]) # [m] + prescribed_motion_body.setR_FcF_F([0.1, 0.0, -0.5]) # [m] + prescribed_motion_body.setR_FM_M([0.0, 0.0, 0.0]) # [m] + prescribed_motion_body.setRPrime_FM_M([0.0, 0.0, 0.0]) # [m/s] + prescribed_motion_body.setRPrimePrime_FM_M([0.0, 0.0, 0.0]) # [m/s^2] + prescribed_motion_body.setOmega_FM_F([0.0, 0.0, 0.0]) # [rad/s] + prescribed_motion_body.setOmegaPrime_FM_F([0.0, 0.0, 0.0]) # [rad/s^2] + prescribed_motion_body.setSigma_FM([0.0, 0.0, 0.0]) + prescribed_motion_body.setOmega_MB_M([0.0, 0.0, 0.0]) # [rad/s] + prescribed_motion_body.setOmegaPrime_MB_B([0.0, 0.0, 0.0]) # [rad/s^2] + prescribed_motion_body.setSigma_MB([0.0, 0.0, 0.0]) + prescribed_motion_body.modelTag = "prescribedMotionBody" + +Note that if these parameters are not set by the user, the vector quantities are set to zero and the matrix and scalar +quantities are set to identity by default. + +#. Add the prescribed state effector to the spacecraft object:: + + scObject.addStateEffector(prescribed_motion_body) + +#. Add the module to the task list:: + + unitTestSim.AddModelToTask(unitTaskName, prescribed_motion_body) + +Make sure to connect the required messages for this module using the kinematic profiler modules if the prescribed motion +body is to be actuated relative to the spacecraft hub. See the example script :ref:`scenarioDeployingSolarArrays` for +more information about how to set up hub-relative multi-body prescribed motion using this state effector module and the +associated kinematic profiler modules. diff --git a/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/spinningBodyOneDOFStateEffector.rst b/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/spinningBodyOneDOFStateEffector.rst index e817c1b31..92da297b3 100644 --- a/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/spinningBodyOneDOFStateEffector.rst +++ b/src/simulation/dynamics/spinningBodies/spinningBodiesOneDOF/spinningBodyOneDOFStateEffector.rst @@ -53,7 +53,9 @@ User Guide ---------- This section is to outline the steps needed to setup a Spinning Body State Effector in Python using Xmera. -#. Import the spinningBodyOneDOFStateEffector class:: +#. Import the spinningBodyOneDOFStateEffector class: + +.. code-block:: python from Xmera.simulation import spinningBodyOneDOFStateEffector @@ -85,7 +87,9 @@ This section is to outline the steps needed to setup a Spinning Body State Effec spinningBody.nameOfThetaState = "spinningBodyTheta" spinningBody.nameOfThetaDotState = "spinningBodyThetaDot" -#. (Optional) Connect a command torque message:: +#. (Optional) Connect a command torque message: + +.. code-block:: python cmdArray = messaging.ArrayMotorTorqueMsgPayload() cmdArray.motorTorque = [cmdTorque] # [Nm] diff --git a/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/spinningBodyTwoDOFStateEffector.rst b/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/spinningBodyTwoDOFStateEffector.rst index 32d29968e..e9bbaaf71 100644 --- a/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/spinningBodyTwoDOFStateEffector.rst +++ b/src/simulation/dynamics/spinningBodies/spinningBodiesTwoDOF/spinningBodyTwoDOFStateEffector.rst @@ -54,7 +54,9 @@ User Guide ---------- This section is to outline the steps needed to setup a Spinning Body 2 DoF State Effector in Python using Xmera. -#. Import the spinningBody2DOFStateEffector class:: +#. Import the spinningBody2DOFStateEffector class: + +.. code-block:: python from Xmera.simulation import spinningBody2DOFStateEffector @@ -98,7 +100,9 @@ This section is to outline the steps needed to setup a Spinning Body 2 DoF State spinningBody.nameOfTheta2State = "spinningBodyTheta2" spinningBody.nameOfTheta2DotState = "spinningBodyTheta2Dot" -#. (Optional) Connect a command torque message:: +#. (Optional) Connect a command torque message: + +.. code-block:: python cmdArray = messaging.ArrayMotorTorqueMsgPayload() cmdArray.motorTorque = [cmdTorque1, cmdTorque2] # [Nm] diff --git a/src/simulation/navigation/simpleNav/simpleNav.rst b/src/simulation/navigation/simpleNav/simpleNav.rst index 65812e6fb..1924370b9 100644 --- a/src/simulation/navigation/simpleNav/simpleNav.rst +++ b/src/simulation/navigation/simpleNav/simpleNav.rst @@ -38,8 +38,8 @@ not come from a noisy sensor but from a ground-based estimation process. * - scEphemOutMsg - :ref:`EphemerisMsgPayload` - spacecraft ephemeris output msg - * - scEphemOutMsg - - :ref:`accelDataOutMsg` + * - accelDataOutMsg + - :ref:`AccDataMsgPayload` - spacecraft accelerometer and gyro output msg * - scStateInMsg - :ref:`SCStatesMsgPayload` diff --git a/src/simulation/onboardDataHandling/instrument/simpleInstrument/simpleInstrument.rst b/src/simulation/onboardDataHandling/instrument/simpleInstrument/simpleInstrument.rst index ef6a8999c..d242b3806 100644 --- a/src/simulation/onboardDataHandling/instrument/simpleInstrument/simpleInstrument.rst +++ b/src/simulation/onboardDataHandling/instrument/simpleInstrument/simpleInstrument.rst @@ -19,7 +19,9 @@ To set up this module users must create a SimpleInstrument instance:: simpleInstrument = simpleInstrument.SimpleInstrument() simpleInstrument.modelTag = "instrument1" -Set the `nodeBaudRate` and `nodeDataName` variables:: +Set the `nodeBaudRate` and `nodeDataName` variables: + +.. code-block:: python instrument.nodeBaudRate = 1200. # baud instrument.nodeDataName = "Instrument 1" # baud diff --git a/src/simulation/onboardDataHandling/spaceToGroundTransmitter/spaceToGroundTransmitter.rst b/src/simulation/onboardDataHandling/spaceToGroundTransmitter/spaceToGroundTransmitter.rst index 2a829878f..24b132efc 100644 --- a/src/simulation/onboardDataHandling/spaceToGroundTransmitter/spaceToGroundTransmitter.rst +++ b/src/simulation/onboardDataHandling/spaceToGroundTransmitter/spaceToGroundTransmitter.rst @@ -45,7 +45,9 @@ To set up this module users must create a SimpleTransmitter instance:: transmitter = spaceToGroundTransmitter.SpaceToGroundTransmitter() transmitter.modelTag = "transmitter" -Set the `nodeBaudRate`, `packetSize`, and numBuffers variables:: +Set the `nodeBaudRate`, `packetSize`, and numBuffers variables: + +.. code-block:: python transmitter.nodeBaudRate = -16000. # baud transmitter.packetSize = -1E6 # bits diff --git a/src/simulation/onboardDataHandling/storageUnit/partitionedStorageUnit.rst b/src/simulation/onboardDataHandling/storageUnit/partitionedStorageUnit.rst index df54cf9fe..956e0525f 100644 --- a/src/simulation/onboardDataHandling/storageUnit/partitionedStorageUnit.rst +++ b/src/simulation/onboardDataHandling/storageUnit/partitionedStorageUnit.rst @@ -28,7 +28,9 @@ To set up this module users must create a PartitionedStorageUnit instance:: storageUnit = partitionedStorageUnit.PartitionedStorageUnit() storageUnit.modelTag = "storageUnit" -In addition to the variables that must be set for the :ref:`DataStorageUnitBase` base class, this module requires the ``storageCapacity`` attribute to be specified. The total data stored in the storageUnit will be limited to not exceed this capacity value:: +In addition to the variables that must be set for the :ref:`DataStorageUnitBase` base class, this module requires the ``storageCapacity`` attribute to be specified. The total data stored in the storageUnit will be limited to not exceed this capacity value: + +.. code-block:: python storageUnit.storageCapacity = 1E5 # Given in bits @@ -40,7 +42,9 @@ Then, the names of the partitions need to be added to the storageUnit using:: storageUnit.addPartition("partitionName") -The ``setDataBuffer()`` method can be used to add or remove a given amount of data from specified partitions:: +The ``setDataBuffer()`` method can be used to add or remove a given amount of data from specified partitions: + +.. code-block:: python storageUnit.setDataBuffer(["partitionName","anotherPartitionName"], [1E4, -1E4]) # Given in bits diff --git a/src/simulation/onboardDataHandling/storageUnit/simpleStorageUnit.rst b/src/simulation/onboardDataHandling/storageUnit/simpleStorageUnit.rst index c8e5e45f1..b3eb9555b 100644 --- a/src/simulation/onboardDataHandling/storageUnit/simpleStorageUnit.rst +++ b/src/simulation/onboardDataHandling/storageUnit/simpleStorageUnit.rst @@ -27,7 +27,9 @@ To set up this module users must create a SimpleStorageUnit instance:: storageUnit = simpleStorageUnit.SimpleStorageUnit() storageUnit.modelTag = "storageUnit" -In addition to the variables that must be set for the :ref:`DataStorageUnitBase` base class, this module requires the ``storageCapacity`` attribute to be specified. The total data stored in the storageUnit will be limited to not exceed this capacity value:: +In addition to the variables that must be set for the :ref:`DataStorageUnitBase` base class, this module requires the ``storageCapacity`` attribute to be specified. The total data stored in the storageUnit will be limited to not exceed this capacity value: + +.. code-block:: python storageUnit.storageCapacity = 1E5 # Given in bits @@ -35,7 +37,9 @@ The next step is to attach one or more :ref:`DataNodeUsageMsgPayload` instances storageUnit.addDataNodeToModel(dataMsg) -The method ``setDataBuffer()`` can be used to add or remove a specific amount of data from the storage unit:: +The method ``setDataBuffer()`` can be used to add or remove a specific amount of data from the storage unit: + +.. code-block:: python storageUnit.setDataBuffer(1E4) # Given in bits diff --git a/src/simulation/onboardDataHandling/transmitter/simpleTransmitter.rst b/src/simulation/onboardDataHandling/transmitter/simpleTransmitter.rst index 5d78a0e7f..a9010429e 100644 --- a/src/simulation/onboardDataHandling/transmitter/simpleTransmitter.rst +++ b/src/simulation/onboardDataHandling/transmitter/simpleTransmitter.rst @@ -41,7 +41,9 @@ To set up this module users must create a SimpleTransmitter instance:: transmitter = simpleTransmitter.SimpleTransmitter() transmitter.modelTag = "transmitter" -Set the `nodeBaudRate`, `packetSize`, and numBuffers variables:: +Set the `nodeBaudRate`, `packetSize`, and numBuffers variables: + +.. code-block:: python transmitter.nodeBaudRate = -16000. # baud transmitter.packetSize = -1E6 # bits diff --git a/src/simulation/power/ReactionWheelPower/ReactionWheelPower.rst b/src/simulation/power/ReactionWheelPower/ReactionWheelPower.rst index cb773b04f..6d6c27578 100644 --- a/src/simulation/power/ReactionWheelPower/ReactionWheelPower.rst +++ b/src/simulation/power/ReactionWheelPower/ReactionWheelPower.rst @@ -124,7 +124,9 @@ common to that base class. Minimum Module Setup ^^^^^^^^^^^^^^^^^^^^ The following code illustrates the minimum module setup within Python assuming the module is -connected to the first RW (thus the ``0`` label):: +connected to the first RW (thus the ``0`` label): + +.. code-block:: python testModule = PowerRW.PowerRW() testModule.modelTag = "bskSat" diff --git a/src/simulation/power/simpleBattery/simpleBattery.rst b/src/simulation/power/simpleBattery/simpleBattery.rst index 362d4e949..bfb6a0316 100644 --- a/src/simulation/power/simpleBattery/simpleBattery.rst +++ b/src/simulation/power/simpleBattery/simpleBattery.rst @@ -26,7 +26,9 @@ To set up this module users must create a SimpleBattery instance:: battery = simpleBattery.SimpleBattery() battery.modelTag = "batteryModel" -In addition to the variables that must be set for the :ref:`PowerStorageBase` base class, this module requires the ``storageCapacity`` attribute to be specified. The total power stored in the battery will be limited to not exceed this capacity value:: +In addition to the variables that must be set for the :ref:`PowerStorageBase` base class, this module requires the ``storageCapacity`` attribute to be specified. The total power stored in the battery will be limited to not exceed this capacity value: + +.. code-block:: python battery.storageCapacity = 10.0 # Given in Joules or Watt-seconds diff --git a/src/simulation/sensors/simpleVoltEstimator/simpleVoltEstimator.rst b/src/simulation/sensors/simpleVoltEstimator/simpleVoltEstimator.rst index 9f3f0b615..d1f1eefcc 100644 --- a/src/simulation/sensors/simpleVoltEstimator/simpleVoltEstimator.rst +++ b/src/simulation/sensors/simpleVoltEstimator/simpleVoltEstimator.rst @@ -35,6 +35,6 @@ User Guide This module is set up similarly to the :ref:`simpleNav` module. It is constructed using ``sVoltObject = simpleVoltEstimator.SimpleVoltEstimator()``. The random walk bound is specified using ``sVoltObject.walkBounds`` and the standard deviation is specified using ``sVoltObject.PMatrix``. Note that the input for the walk bound and -standard deviation must be a list to work for the :ref:`gauss_markov` module. +standard deviation must be a list to work for the ``gauss_markov`` module. -If no walk bound or standard deviation is specified, then the voltage measurement will not be corrupted with noise. \ No newline at end of file +If no walk bound or standard deviation is specified, then the voltage measurement will not be corrupted with noise. diff --git a/src/simulation/vizard/dataFileToViz/dataFileToViz.rst b/src/simulation/vizard/dataFileToViz/dataFileToViz.rst index 75bda5a1c..82752e156 100644 --- a/src/simulation/vizard/dataFileToViz/dataFileToViz.rst +++ b/src/simulation/vizard/dataFileToViz/dataFileToViz.rst @@ -2,7 +2,7 @@ Executive Summary ----------------- This module reads in simulation data of one or more spacecraft, likely created outside of Xmera, -and creates associated Xmera messages such that :ref:`vizInterface` can stream of save a :ref:`Vizard ` +and creates associated Xmera messages such that :ref:`vizInterface` can stream of save a Vizard compatible data file. This makes it possible to use Vizard to illustrate a simulation. The use of this module is demonstrates in :ref:`scenarioDataToViz`. @@ -116,7 +116,7 @@ spacecraft contains 2 clusters (ADCS and DV) which contain one thruster each. These steps must be done for each spacecraft in the data file. If a spacecraft does not have thrusters, then an empty thruster cluster vector must be added for that spacecraft. -See :ref:`test_dataFileToViz` for an example on how to configure for thruster information. +See ``test_dataFileToViz`` for an example on how to configure for thruster information. .. code-block:: python diff --git a/src/simulation/vizard/vizInterface/vizInterface.rst b/src/simulation/vizard/vizInterface/vizInterface.rst index b478bf7d4..7a003a49e 100644 --- a/src/simulation/vizard/vizInterface/vizInterface.rst +++ b/src/simulation/vizard/vizInterface/vizInterface.rst @@ -1,7 +1,7 @@ Executive Summary ----------------- -This module provides an interface to package up Xmera messages and pass them onto the :ref:`Vizard ` +This module provides an interface to package up Xmera messages and pass them onto the Vizard application. This allows for the Xmera simulation data to be recorded to a file for play-back, or for live streaming of the simulation data. It is possible to record the simulation data of a single spacecraft or a multitude of spacecraft. @@ -36,7 +36,7 @@ The following messages are set directly within ``vizInterface``. Additional mes - :ref:`SpicePlanetStateMsgPayload` - (optional) vector of input messages of planet Spice data -The ``VizSpacecraftData`` structure, defined in :ref:`vizStructures`, contains a range of input messages for each spacecraft added. +The ``VizSpacecraftData`` structure, defined in ``vizStructures``, contains a range of input messages for each spacecraft added. .. list-table:: ``VizSpacecraftData`` input messages per spacecraft :widths: 25 25 50 @@ -61,6 +61,6 @@ The ``VizSpacecraftData`` structure, defined in :ref:`vizStructures`, contains a User Guide ---------- -The ``vizInterface`` module can be directly configured, or setup using the helper methods in :ref:`vizSupport`. -More information can be found in :ref:`vizardSettings` page. The :ref:`scenarioFormationBasic` illustrates and +The ``vizInterface`` module can be directly configured, or setup using the helper methods in ``vizSupport``. +More information can be found in ``vizardSettings`` page. The :ref:`scenarioFormationBasic` illustrates and discusses how to configure ``vizInterface`` for use with multiple satellites.