diff --git a/.gen-run-complete.sh b/.gen-run-complete.sh index e71ce07..a3a7764 100644 --- a/.gen-run-complete.sh +++ b/.gen-run-complete.sh @@ -1,26 +1,39 @@ #!/bin/bash - _run_sh_completions() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - opts="docker-build build inspect exec gds gen-deps teardown update sync test topology --daemon --persist --debug --as-host --local --clean --host-thread-ctl --help --force" + + # Main commands + local commands="docker-build build inspect exec update teardown topology sync" + # Options/flags + local flags="--daemon --debug --as-host --clean --host-thread-ctrl --help" + # All options combined + local opts="$commands $flags" if [[ ${cur} == -* ]]; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + # If current word starts with a dash, complete with flags + COMPREPLY=( $(compgen -W "${flags}" -- ${cur}) ) return 0 fi case "${prev}" in inspect) - # You can add container names here if you want to provide completion for specific containers + # Container names for inspect command local containers="fsw gds" COMPREPLY=( $(compgen -W "${containers}" -- ${cur}) ) return 0 ;; + exec) + # Executable targets + local targets="gds FlightComputer test" + COMPREPLY=( $(compgen -W "${targets}" -- ${cur}) ) + return 0 + ;; *) + # Default to main commands and flags COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 ;; diff --git a/.gitignore b/.gitignore index b248cd0..99b741a 100644 --- a/.gitignore +++ b/.gitignore @@ -63,7 +63,7 @@ core *TopologyAppID.csv *TopologyAppAi_IDTableLog.txt -.vscode +# .vscode py_dict .settings build-fprime-automatic* diff --git a/.org_out/FlightSM.png b/.org_out/FlightSM.png new file mode 100644 index 0000000..a66f1e1 Binary files /dev/null and b/.org_out/FlightSM.png differ diff --git a/.org_out/LegacyDeploymentLink.png b/.org_out/LegacyDeploymentLink.png new file mode 100644 index 0000000..cc0d6d6 Binary files /dev/null and b/.org_out/LegacyDeploymentLink.png differ diff --git a/.org_out/NewDeploymentLink.png b/.org_out/NewDeploymentLink.png new file mode 100644 index 0000000..cab8299 Binary files /dev/null and b/.org_out/NewDeploymentLink.png differ diff --git a/.org_out/run.png b/.org_out/run.png index 7ff5ad9..a7de3ca 100644 Binary files a/.org_out/run.png and b/.org_out/run.png differ diff --git a/.vscode/launch.json b/.vscode/launch.json index 4ffac02..665b4ff 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,65 +1,201 @@ { - "version": "0.2.0", - "configurations": [ - { - "name": "Launch Program in Docker", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceFolder}/FlightComputer/build-artifacts/Linux/FlightComputer/bin/FlightComputer", - "args": ["-a", "127.0.0.1", "-u", "${env:UPLINK_TARGET_PORT}", "-d", "${env:DOWNLINK_TARGET_PORT}"], - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [ + "version": "0.2.0", + "configurations": [ { - "name": "FSW_IMG", - "value": "${env:FSW_IMG}" - } - ], - "MIMode": "gdb", - "miDebuggerPath": "/usr/bin/gdb", - "setupCommands": [ + "name": "Python attach local", + "type": "python", + "request": "attach", + "connect": { + "host": "localhost", + "port": 5678 + }, + "cwd": "${workspaceFolder}/deploy", + "console": "integratedTerminal", + "justMyCode": false + }, { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - } - ], - "externalConsole": false, - "pipeTransport": { - "pipeProgram": "docker", - "pipeArgs": [ - "exec", - "-i", - "fsw", - "gdbserver", - ":${env:GDB_PORT}", - "/fsw/target/build-artifacts/Linux/FlightComputer/bin/FlightComputer" - ], - "debuggerPath": "/usr/bin/gdb" - }, - "sourceFileMap": { - "/fsw": "${workspaceFolder}/fsw" - } - }, - { - "name": "Attach to Program in Docker", - "type": "cppdbg", - "request": "attach", - "program": "${workspaceFolder}/build-artifacts/Linux/FlightComputer/bin/FlightComputer", - "processId": "${command:pickProcess}", - "MIMode": "gdb", - "miDebuggerServerAddress": "localhost:${env:GDB_PORT}", - "miDebuggerPath": "/usr/bin/gdb", - "setupCommands": [ + "name": "MBSE Python attach in docker", + "type": "python", + "request": "attach", + "connect": { + "host": "localhost", + "port": 5678 + }, + "cwd": "${workspaceFolder}/scripts", + "console": "integratedTerminal", + "justMyCode": false, + "pathMappings": [ + { + "localRoot": "/home/reggiemarr/Projects/MBSE_FSW/", + "remoteRoot": "/MBSE_FSW" + }, + { + "localRoot": "/home/reggiemarr/Projects/MBSE_FSW/scripts/", + "remoteRoot": "/MBSE_FSW/scripts" + } + ] + }, + { + "name": "run deployment", + "type": "python", + "request": "launch", + "args": [ + "${workspaceFolder}/run-paramiko.py" + ], + "console": "integratedTerminal", + "justMyCode": false + }, + { + "name": "(gdb) Launch Docker App", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/FlightComputer/build-artifacts/Linux/FlightComputer/bin/FlightComputer", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "miDebuggerServerAddress": "localhost:5555", + "environment": [], + "externalConsole": true, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Docker Debug", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "Attach debug Flight SW" + }, + { + "name": "Attach to Flight SW on local", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/FlightComputer/build-artifacts/Linux/FlightComputer/bin/FlightComputer", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "miDebuggerServerAddress": "localhost:5555", + "environment": [], + "useExtendedRemote": true, + "externalConsole": false, + "MIMode": "gdb", + "sourceFileMap": { + "/fsw": "${workspaceFolder}" + } + }, + { + "name": "Launch GDS Integration tests", + "type": "python", + "request": "launch", + "connect": { + "host": "localhost", + "port": 5678 + }, + "program": "${file}", + "console": "externalTerminal", + "pathMappings": [ + { + "localRoot": "${workspaceFolder}", + "remoteRoot": "/home/fprime/flightcomputer-software" + } + ] + }, + { + "name": "Attach GDS Integration Test Runner", + "type": "python", + "request": "attach", + "connect": { + "host": "172.29.1.5", + "port": 5678 + }, + "program": "${file}", + "console": "externalTerminal", + "pathMappings": [ + { + "localRoot": "${workspaceFolder}", + "remoteRoot": "/home/fprime/flightcomputer-software" + } + ], + "postDebugTask": "Teardown Integration Tests" + }, + { + "name": "Launch Flight SW in docker", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/FlightComputer/build-artifacts/Linux/FlightComputer/bin/FlightComputer", + "args": [ + "-a", + "127.1.1.1", + "-u", + "50050", + "-d", + "50000" + ], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb", + "sourceFileMap": { + "/fsw/": "${workspaceFolder}" + }, + "pathMappings": [ + { + "localRoot": "${workspaceFolder}", + "remoteRoot": "/fsw/" + } + ], + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "pipeCwd": "${workspaceFolder}", + "pipeProgram": "docker", + "pipeArgs": [ + "compose", + "run", + "-i", + "fsw", + "bash", + "-c" + ], + "debuggerPath": "/usr/bin/gdb", + "preLaunchTask": "Build Flight SW" + }, { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true + "name": "Launch Flight SW on host", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/FlightComputer/build-artifacts/Linux/FlightComputer/bin/FlightComputer", + "args": [ + "-a", + "127.0.0.1", + "-u", + "50000", + "-d", + "50050" + ], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb", + "useExtendedRemote": true, + "sourceFileMap": { + "/fsw/": "${workspaceFolder}" + }, + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] } - ], - "sourceFileMap": { - "/fsw": "${workspaceFolder}/fsw" - } - } - ] + ] } diff --git a/FlightComputer/CCSDSTester/CCSDSTester.cpp b/FlightComputer/CCSDSTester/CCSDSTester.cpp index 0151bb9..f30ae82 100644 --- a/FlightComputer/CCSDSTester/CCSDSTester.cpp +++ b/FlightComputer/CCSDSTester/CCSDSTester.cpp @@ -122,7 +122,7 @@ void CCSDSTester::PING_cmdHandler(const FwOpcodeType opCode, const U32 cmdSeq) { U32 dfltMessage = 0x9944fead; com.resetSer(); - U8 packetType = Fw::ComPacket::ComPacketType::FW_PACKET_COMMAND; + Fw::ComPacket::ComPacketType packetType = Fw::ComPacket::ComPacketType::FW_PACKET_COMMAND; com.serialize(packetType); com.serialize(dfltMessage); @@ -142,7 +142,6 @@ void CCSDSTester::MESSAGE_cmdHandler(const FwOpcodeType opCode, com.resetSer(); // U32 starter = 0xFFFF; // com.serialize(starter); - // Fw::ComPacket::ComPacketType_t packetType = Fw::ComPacket::ComPacketType_e::FW_PACKET_FILE; U8 packetType = Fw::ComPacket::ComPacketType::FW_PACKET_FILE; com.serialize(packetType); com.serialize(str1); diff --git a/README.org b/README.org index 64d18d7..48f4e4b 100644 --- a/README.org +++ b/README.org @@ -14,8 +14,8 @@ The project is containerized with Docker, ensuring compatibility across various **** Clone the repo and submodules #+BEGIN_SRC bash #Get the repo -git clone git@github.com:ReggieMarr/MBSE_FSW.git -cd MBSE_FSW +git clone git@github.com:ReggieMarr/space-vehicle-system.git +cd space-vehicle-system #pull in the submodules git submodule update --init --recursive #+END_SRC @@ -28,57 +28,63 @@ Commands are summarized as such: @startuml skinparam actorStyle awesome actor User - -rectangle "" { +rectangle "Commands" { [Docker Build] [Project Build] [Container Inspection] - [FlightSoftware Execution] - [GDS Execution] - [Dependency Generation] + [Execution Commands] + note right of [Execution Commands] + exec command with subcommands: + - FlightComputer + - gds + - test + end note [Environment Teardown] [Update] [Sync] - [Test] [Topology Visualization] } - cloud "Docker Environment" { [Docker Image] [FSW Container] [GDS Container] } - database "Host File System" { folder "Project Files" folder "Build Artifacts" - folder "Dependencies" } - User --> [Docker Build] : docker-build User --> [Project Build] : build User --> [Container Inspection] : inspect -User --> [FlightSoftware Execution] : exec -User --> [GDS Execution] : gds -User --> [Dependency Generation] : gen-deps +User --> [Execution Commands] : exec +[Execution Commands] --> [FlightComputer Execution] +[Execution Commands] --> [GDS Execution] +[Execution Commands] --> [Test Execution] User --> [Environment Teardown] : teardown User --> [Update] : update User --> [Sync] : sync -User --> [Test] : test User --> [Topology Visualization] : topology [Docker Build] --> [Docker Image] : Creates/Updates [Project Build] --> [Build Artifacts] : Generates [Container Inspection] --> [FSW Container] : Provides shell -[FlightSoftware Execution] --> [FSW Container] : Runs FlightSoftware +[FlightComputer Execution] --> [FSW Container] : Runs FlightSoftware [GDS Execution] --> [GDS Container] : Runs GDS -[Dependency Generation] --> [Dependencies] : Extracts +[Test Execution] --> [GDS Container] : Runs tests [Environment Teardown] --> [Docker Environment] : Removes containers [Update] --> [Docker Image] : Pulls latest images [Sync] --> [Docker Image] : Pushes local changes -[Test] --> [GDS Container] : Runs tests [Topology Visualization] --> [Project Files] : Generates topology diagram +note right of User + Available flags: + --daemon + --debug + --as-host + --clean + --host-thread-ctrl + --help +end note @enduml #+end_src @@ -99,29 +105,25 @@ Options: --daemon Run as daemon --debug Enable debug mode --as-host Run as host - --persist Ignore startup issues and keep running - --local Use local environment --clean Clean build - --host-thread-ctl Set thread control + --host-thread-ctl Set thread control for running without sudo (this itself requires sudo) --help Show this help message - Commands: + update Build the Docker image docker-build Build the Docker image build Build the project inspect [container] Inspect a container - exec Execute the FlightComputer - gds Run the GDS - update Pulls the latest version of docker images - sync Pushes local changes and updates docker images - gen-deps Generate dependencies (for editor mapping) + exec gds Run the GDS + exec FlightComputer Run the Flight Software + exec test Run integration tests against the Flight Software + update Pull latest Docker images teardown Tear down the environment - test Run tests topology Generate topology visualization #+END_SRC One use case is building and running the deployment, this can be done like so (note building clean is only necessary when making significant changes): #+begin_src bash -❯ ./run.sh build --clean && ./run.sh exec --local +❯ ./run.sh build --clean && ./run.sh exec FlightComputer #+end_src This then provides a web based ui that can be viewed by visiting http://127.0.0.1:5000/#Channels on your preferred web browser. @@ -129,7 +131,6 @@ This then provides a web based ui that can be viewed by visiting http://127.0.0. *Note* this example runs a standard version of ~fprime-gds~ and deploys it locally. More information about the Web UI can be found [[https://nasa.github.io/fprime/UsersGuide/gds/gds-introduction.html][here]]. *** Additional Tips - - Combine flags: ~./run.sh --clean --debug exec~ - Script uses environment variables from .env file in the same directory - Use ~--daemon~ flag to run processes in the background - Use ~--host-thread-ctl~ when building for non-sudo host execution thread control @@ -177,3 +178,46 @@ IN_FLIGHT --> IDLE: TERMINATE #+RESULTS: [[file:.org_out/FlightSM.svg]] + +* CCSDS support + +** Communication Topology Comparison +*** Legacy +[[file:.org_out/LegacyDeploymentLink.png]] +*** New +[[file:.org_out/NewDeploymentLink.png]] +** Arch Layout + +#+BEGIN_SRC plantuml :file .org_out/revisedCommsArch.jpg +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml +title Updated Comms Architecture + +Container_Boundary(obc, "OBC", "Flight Software Deployment") { + Component(eventLogger, "Event Logger", "Svc.ActiveLogger") + Component(tlmChan, "Tlm Chan", "Svc.TlmChan") + Component(obcPacketFramer, "Packet Framer", "Svc.PacketFramer") + Component(obcMessageFramer, "Message Framer", "Svc.Framer") + Component(obcDeframer, "Deframer", "Svc.Deframer") + Component(obcPacketAccumulator, "Packet Accumulator", "Svc.PacketAccumulator") + Component(obcFrameAccumulator, "Frame Accumulator", "Svc.FrameAccumulator") +} + +Component(commLink, "Communications Link", "Transport Layer") + +Container_Boundary(groundControl, "Ground Dep", "Ground Software Deployment") { + Component(cspInterface, "CSP/CCSDS Interface", "Protocol adapter") + Component(actuator, "Actuator Module", "Control execution") + Component(daq, "Data acquisition Module", "Collects data via drivers") +} + + +' External Relations +Rel(obc, rioNode, "Commands", "CSP over UART/CAN") +Rel(obc, rioNode, "Polls", "CSP over UART/CAN") +Rel(daq, pressure, "Reads", "ADC") +Rel(daq, temperature, "Reads", "SPI") +Rel(actuator, valve, "Controls", "Digital") +Rel(actuator, heater, "Controls", "PWM") +@enduml +#+end_src diff --git a/fprime b/fprime index 7cc3b79..47c0fc4 160000 --- a/fprime +++ b/fprime @@ -1 +1 @@ -Subproject commit 7cc3b79f06f1f953282ca9576323b6d005c1d125 +Subproject commit 47c0fc4cc828ecf863acd3d65a43e541c192d738 diff --git a/run.sh b/run.sh index 2fd6347..e2ed6b0 100755 --- a/run.sh +++ b/run.sh @@ -36,8 +36,10 @@ Commands: inspect [container] Inspect a container exec gds Run the GDS exec FlightComputer Run the Flight Software + exec test Run integration tests against the Flight Software update Pull latest Docker images teardown Tear down the environment + topology Generate topology visualization EOF } @@ -46,11 +48,13 @@ AS_HOST=0 DAEMON=0 DEBUG=0 SET_THREAD_CTRL=0 +FORCE=0 # Process flags for arg in "$@"; do case $arg in --daemon) DAEMON=1 ;; + --force) FORCE=1 ;; --debug) DEBUG=1 ;; --as-host) AS_HOST=1 ;; --clean) CLEAN=1 ;; @@ -104,7 +108,11 @@ case $1 in ;; "update") - exec_cmd "git submodule sync && git submodule update --init --recursive && docker pull $FSW_IMG" + PULL_CMD="git pull" + [ "$FORCE" -eq 1 ] && PULL_CMD="git fetch -a && git reset --hard origin/$(git rev-parse --abbrev-ref HEAD)" + PULL_CMD+=" && git submodule sync && git submodule update --init --recursive" + + exec_cmd "$PULL_CMD" ;; "docker-build") @@ -114,8 +122,15 @@ case $1 in [[ $REPLY =~ ^[Yy]$ ]] || { echo "Build cancelled."; exit 1; } fi - if [ "$(git rev-parse HEAD)" != "$(git ls-remote $(git rev-parse --abbrev-ref @{u} | sed 's/\// /g') | cut -f1)" ]; then - read -p "Current commit not pushed. Continue? (y/n) " -n 1 -r + # Fetch from remote to ensure we have latest refs + git fetch -q origin + + # Get current commit hash + CURRENT_COMMIT=$(git rev-parse HEAD) + + # Check if current commit exists in any remote branch + if ! git branch -r --contains "$CURRENT_COMMIT" | grep -q "origin/"; then + read -p "Current commit not found in remote repository. Continue? (y/n) " -n 1 -r echo [[ $REPLY =~ ^[Yy]$ ]] || { echo "Build cancelled."; exit 1; } fi @@ -180,6 +195,12 @@ case $1 in esac ;; + "topology") + # NOTE set working dir when we link this to a CI/CD + CMD="fprime-util visualize -p ${DEPLOYMENT_ROOT}/Top -r ${DEPLOYMENT_ROOT}" + run_docker_compose "fsw bash -c \"$CMD\"" + ;; + "teardown") echo "Tearing down FSW..." docker compose down