diff --git a/.gitattributes b/.gitattributes
index 4e8a4875..b0c5febf 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -3,3 +3,6 @@
# Declare files that will always have LF line endings on checkout.
*.sh text eol=lf
+
+# Handle PNGs as binary
+*.png binary
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..28419fdf
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,48 @@
+name: Build
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ fsw:
+ runs-on: ubuntu-latest
+ container:
+ image: ivvitc/nos3-64:dev
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ - name: Update
+ run: apt-get update
+ - name: Install dependencies
+ run: apt-get install -y python3 docker docker.io
+ - name: prep
+ run: make prep
+ - name: config
+ run: make config
+ - name: build directory
+ run: mkdir ./fsw/build
+ - name: build
+ run: make build-fsw
+
+ sim:
+ runs-on: ubuntu-latest
+ container:
+ image: ivvitc/nos3-64:dev
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ submodules: recursive
+ - name: Update
+ run: apt-get update
+ - name: Install dependencies
+ run: apt-get install -y python3 docker docker.io
+ - name: prep
+ run: make prep
+ - name: config
+ run: make config
+ - name: build directory
+ run: mkdir ./sims/build
+ - name: build
+ run: make build-sim
diff --git a/Makefile b/Makefile
index bc70c7ed..97c2885b 100644
--- a/Makefile
+++ b/Makefile
@@ -4,6 +4,7 @@
BUILDTYPE ?= debug
INSTALLPREFIX ?= exe
FSWBUILDDIR ?= $(CURDIR)/fsw/build
+GSWBUILDDIR ?= $(CURDIR)/gsw/build
SIMBUILDDIR ?= $(CURDIR)/sims/build
export CFS_APP_PATH = ../components
@@ -45,6 +46,11 @@ all:
$(MAKE) sim
$(MAKE) gsw
+build-cryptolib:
+ mkdir -p $(GSWBUILDDIR)
+ cd $(GSWBUILDDIR) && cmake $(PREP_OPTS) -DSUPPORT=1 ../../components/cryptolib
+ $(MAKE) --no-print-directory -C $(GSWBUILDDIR)
+
build-fsw:
ifeq($(FLIGHT_SOFTWARE), fprime)
cd fsw/fprime/fprime-nos3
@@ -64,7 +70,7 @@ build-sim:
$(MAKE) --no-print-directory -C $(SIMBUILDDIR) install
checkout:
- ./scripts/checkout.sh
+ ./scripts/docker_checkout.sh
clean:
$(MAKE) clean-fsw
@@ -83,6 +89,7 @@ clean-sim:
rm -rf sims/build
clean-gsw:
+ rm -rf gsw/build
rm -rf gsw/cosmos/build
rm -rf /tmp/nos3
@@ -99,6 +106,7 @@ fsw:
./cfg/build/fsw_build.sh
gsw:
+ ./scripts/docker_build_cryptolib.sh
./cfg/build/gsw_build.sh
launch:
@@ -123,3 +131,6 @@ stop:
stop-gsw:
./scripts/stop_gsw.sh
+
+igniter:
+ ./scripts/igniter_launch.sh
diff --git a/README.md b/README.md
index ac21e10f..61a19ae8 100644
--- a/README.md
+++ b/README.md
@@ -7,15 +7,17 @@ The best source of documentation can be found at [the wiki](https://github.com/n
### Prerequisites
Each of the applications listed below are required prior to performing the installation procedure:
-* Option A
+* Option A, you already use Linux
* [Git 2.36+](https://git-scm.com/)
* Linux with docker and docker compose installed
-* Option B
+* Option B, deployment of a virtual machine (VM)
* [Git 2.36+](https://git-scm.com/)
* [Vagrant 2.3.4+](https://www.vagrantup.com/)
* [VirtualBox 7.0+](https://www.virtualbox.org/)
### Installing
+Option B only.
+Will provision a VM with all required packages installed to be used immediately.
1. Clone the repository `git clone https://github.com/nasa/nos3.git`
2. `cd nos3`
3. Clone the submodules `git submodule update --init --recursive`
@@ -77,7 +79,11 @@ This project is licensed under the NOSA (NASA Open Source Agreement) License.
Please report issues and request features on the GitHub tracking system - [NOS3 Issues](https://www.github.com/nasa/nos3/issues).
## Contributions
-If you would like to contribute to the repository, please complete the [NOS3_Indv_CLA](./doc/NOS3_Indv_CLA.pdf) form and submit it to gsfc-softwarerequest@mail.nasa.gov with John.P.Lucas@nasa.gov copied. Next please create an issue capturing work to be done noting you intend to work it, a related branch, and submit a pull request when ready and we'll work to get it integrated.
+If you would like to contribute to the repository, please complete this [NASA Form][def] and submit it to gsfc-softwarerequest@mail.nasa.gov with John.P.Lucas@nasa.gov CC'ed.
+Next, please create an issue describing the work to be performed noting that you intend to work it, create a related branch, and submit a pull request when ready. When complete, we will review and work to get it integrated.
## Support
If this project interests you or if you have any questions, please feel free to contact any developer directly or email `support@nos3.org`.
+
+
+[def]: https://github.com/nasa/nos3/files/14578604/NOS3_Invd_CLA.pdf "NOS3 NASA Contributor Form PDF"
\ No newline at end of file
diff --git a/cfg/InOut/Inp_IPC.txt b/cfg/InOut/Inp_IPC.txt
index e7f7a534..1e2bc0d8 100644
--- a/cfg/InOut/Inp_IPC.txt
+++ b/cfg/InOut/Inp_IPC.txt
@@ -1,15 +1,5 @@
<<<<<<<<<<<<<<< 42: InterProcess Comm Configuration File >>>>>>>>>>>>>>>>
-17 ! Number of Sockets
-********************************** Sample IPC *****************************
-TX ! IPC Mode (OFF,TX,RX,TXRX,ACS,WRITEFILE,READFILE)
-0 ! AC.ID for ACS mode
-"State00.42" ! File name for WRITE or READ
-SERVER ! Socket Role (SERVER,CLIENT,GMSEC_CLIENT)
-fortytwo 4242 ! Server Host Name, Port
-FALSE ! Allow Blocking (i.e. wait on RX)
-FALSE ! Echo to stdout
-1 ! Number of TX prefixes
-"SC" ! Prefix 0
+16 ! Number of Sockets
********************************** RW 0 to 42 *****************************
RX ! IPC Mode (OFF,TX,RX,TXRX,ACS,WRITEFILE,READFILE)
0 ! AC.ID for ACS mode
diff --git a/cfg/gui/.gitignore b/cfg/gui/.gitignore
new file mode 100644
index 00000000..cb8a7669
--- /dev/null
+++ b/cfg/gui/.gitignore
@@ -0,0 +1,3 @@
+*.ui
+*.ui.*
+__pycache__
\ No newline at end of file
diff --git a/cfg/gui/cfg_gui.ui b/cfg/gui/cfg_gui.ui
new file mode 100644
index 00000000..02234ade
--- /dev/null
+++ b/cfg/gui/cfg_gui.ui
@@ -0,0 +1,1198 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 658
+ 655
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 170
+ 170
+ 170
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 220
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 170
+ 170
+ 170
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 220
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 170
+ 170
+ 170
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 220
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+
+ Form
+
+
+
+
+ 0
+ 0
+ 661
+ 661
+
+
+
+ QTabWidget::TabShape::Rounded
+
+
+ 0
+
+
+
+ Config
+
+
+
+
+ 130
+ 20
+ 421
+ 26
+
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ true
+
+
+ None
+
+
+
+
+
+ 550
+ 20
+ 94
+ 26
+
+
+
+ Browse...
+
+
+
+
+
+ 10
+ 20
+ 121
+ 21
+
+
+
+ Current Config:
+
+
+
+
+
+ 10
+ 260
+ 631
+ 321
+
+
+
+ Spacecraft Config
+
+
+
+
+ 0
+ 20
+ 631
+ 301
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ true
+
+
+ Qt::ScrollBarPolicy::ScrollBarAlwaysOn
+
+
+ Qt::ScrollBarPolicy::ScrollBarAlwaysOff
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 613
+ 68
+
+
+
+
+ 0
+ 0
+
+
+
+
+ QLayout::SizeConstraint::SetDefaultConstraint
+
+
+
+
+
+
+
+
+
+
+ 150
+ -1
+ 48
+ 21
+
+
+
+ 1
+
+
+
+
+
+
+ 10
+ 60
+ 631
+ 181
+
+
+
+ Master Config
+
+
+
+
+ 0
+ 20
+ 631
+ 161
+
+
+
+ -
+
+
+ false
+
+
+
+
+
+
+
+
+
+ 220
+ 590
+ 94
+ 26
+
+
+
+ Save
+
+
+
+
+
+ 330
+ 590
+ 94
+ 26
+
+
+
+ Save As...
+
+
+
+
+
+ 50
+ 585
+ 111
+ 41
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 480
+ 585
+ 131
+ 41
+
+
+
+
+
+
+ true
+
+
+ Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter
+
+
+
+
+
+ Build
+
+
+
+
+ 10
+ 120
+ 631
+ 491
+
+
+
+ Console Output
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ false
+
+
+ false
+
+
+
+
+ 0
+ 20
+ 631
+ 471
+
+
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+ 10
+ 20
+ 641
+ 81
+
+
+
+ QFrame::Shape::StyledPanel
+
+
+ QFrame::Shadow::Raised
+
+
+
+
+ 79
+ 0
+ 561
+ 80
+
+
+
+ QFrame::Shape::StyledPanel
+
+
+ QFrame::Shadow::Raised
+
+
+
+
+ 0
+ 0
+ 561
+ 80
+
+
+
+ -
+
+
+ All
+
+
+
+ -
+
+
+ All
+
+
+
+ -
+
+
+ FSW
+
+
+
+ -
+
+
+ CFG
+
+
+
+ -
+
+
+ SIM
+
+
+
+ -
+
+
+ SIM
+
+
+
+ -
+
+
+ GSW
+
+
+
+ -
+
+
+ FSW
+
+
+
+ -
+
+
+ GSW
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 81
+ 41
+
+
+
+ QFrame::Shape::StyledPanel
+
+
+ QFrame::Shadow::Raised
+
+
+
+
+ 0
+ 0
+ 81
+ 41
+
+
+
+ -
+
+
+ Build
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+
+
+
+
+
+
+
+ 0
+ 40
+ 81
+ 41
+
+
+
+ QFrame::Shape::StyledPanel
+
+
+ QFrame::Shadow::Raised
+
+
+
+
+ 0
+ 0
+ 81
+ 41
+
+
+
+ -
+
+
+ Clean
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+
+
+
+
+
+
+
+
+ Launch
+
+
+
+
+ 10
+ 10
+ 631
+ 611
+
+
+
+
+
+
+
+
+ 10
+ 570
+ 611
+ 31
+
+
+
+
+ 45
+
+ -
+
+
+ Play
+
+
+
+ ../../../../../../../../usr/share/icons/Humanity/actions/24/gtk-media-play-ltr.svg../../../../../../../../usr/share/icons/Humanity/actions/24/gtk-media-play-ltr.svg
+
+
+
+ -
+
+
+ Pause
+
+
+
+ ../../../../../../../../usr/share/icons/Humanity/actions/24/media-playback-pause.svg../../../../../../../../usr/share/icons/Humanity/actions/24/media-playback-pause.svg
+
+
+
+
+
+
+
+
+ 10
+ 10
+ 611
+ 41
+
+
+
+ -
+
+
+ Launch
+
+
+
+ -
+
+
+ Stop
+
+
+
+
+
+
+
+
+ 10
+ 60
+ 611
+ 451
+
+
+
+ NOS3 Time Driver
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ false
+
+
+ false
+
+
+
+
+ 0
+ 20
+ 611
+ 431
+
+
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+ 190
+ 520
+ 261
+ 41
+
+
+
+ -
+
+
-
+
+
+
+
+ -
+
+ Run For
+
+
+ -
+
+ Run Until
+
+
+
+
+ -
+
+
+
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cfg/gui/cfg_gui.ui.nIFTUJ b/cfg/gui/cfg_gui.ui.nIFTUJ
new file mode 100644
index 00000000..6af78023
--- /dev/null
+++ b/cfg/gui/cfg_gui.ui.nIFTUJ
@@ -0,0 +1,1112 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 655
+ 655
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 170
+ 170
+ 170
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 220
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 170
+ 170
+ 170
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 220
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 170
+ 170
+ 170
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 255
+ 255
+ 220
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 127
+ 127
+ 127
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+
+ Form
+
+
+
+
+ 0
+ 0
+ 661
+ 661
+
+
+
+ QTabWidget::Rounded
+
+
+ 0
+
+
+
+ Config
+
+
+
+
+ 130
+ 20
+ 421
+ 26
+
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+ None
+
+
+
+
+
+ 550
+ 20
+ 94
+ 26
+
+
+
+ Browse...
+
+
+
+
+
+ 10
+ 20
+ 121
+ 21
+
+
+
+ Current Config:
+
+
+
+
+
+ 10
+ 300
+ 631
+ 281
+
+
+
+ Spacecraft Config
+
+
+
+
+ 0
+ 20
+ 631
+ 261
+
+
+
+ -
+
+
+ QTextEdit::NoWrap
+
+
+ false
+
+
+
+
+
+
+
+
+ 150
+ -1
+ 48
+ 21
+
+
+
+ 1
+
+
+
+
+
+
+ 10
+ 60
+ 631
+ 231
+
+
+
+ Master Config
+
+
+
+
+ 0
+ 20
+ 631
+ 211
+
+
+
+ -
+
+
+ false
+
+
+
+
+
+
+
+
+
+ 220
+ 590
+ 94
+ 26
+
+
+
+ Save
+
+
+
+
+
+ 330
+ 590
+ 94
+ 26
+
+
+
+ Save As...
+
+
+
+
+
+ Build
+
+
+
+
+ 10
+ 120
+ 631
+ 491
+
+
+
+ Console Output
+
+
+ false
+
+
+ false
+
+
+
+
+ 0
+ 20
+ 631
+ 471
+
+
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+ 110
+ 20
+ 421
+ 81
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 79
+ 0
+ 341
+ 80
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 0
+ 0
+ 340
+ 80
+
+
+
+ -
+
+
+ FSW
+
+
+
+ -
+
+
+ FSW
+
+
+
+ -
+
+
+ GSW
+
+
+
+ -
+
+
+ SIM
+
+
+
+ -
+
+
+ SIM
+
+
+
+ -
+
+
+ GSW
+
+
+
+ -
+
+
+ All
+
+
+
+ -
+
+
+ All
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 81
+ 41
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 0
+ 0
+ 81
+ 41
+
+
+
+ -
+
+
+ Build
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+ 0
+ 40
+ 81
+ 41
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ 0
+ 0
+ 81
+ 41
+
+
+
+ -
+
+
+ Clean
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+ Launch
+
+
+
+
+ 10
+ 10
+ 631
+ 611
+
+
+
+
+
+
+
+
+ 10
+ 570
+ 611
+ 31
+
+
+
+
+ 45
+
+ -
+
+
+ Play
+
+
+
+ ../../../../../../../../usr/share/icons/Humanity/actions/24/gtk-media-play-ltr.svg../../../../../../../../usr/share/icons/Humanity/actions/24/gtk-media-play-ltr.svg
+
+
+
+ -
+
+
+ Pause
+
+
+
+ ../../../../../../../../usr/share/icons/Humanity/actions/24/media-playback-pause.svg../../../../../../../../usr/share/icons/Humanity/actions/24/media-playback-pause.svg
+
+
+
+
+
+
+
+
+ 10
+ 10
+ 611
+ 41
+
+
+
+ -
+
+
+ Launch
+
+
+
+ -
+
+
+ Stop
+
+
+
+
+
+
+
+
+ 10
+ 60
+ 611
+ 451
+
+
+
+ Console Output
+
+
+ false
+
+
+ false
+
+
+
+
+ 0
+ 20
+ 611
+ 431
+
+
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 255
+ 255
+ 255
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+ 200
+ 530
+ 93
+ 26
+
+
+ -
+
+ Run For
+
+
+ -
+
+ Run Until
+
+
+
+
+
+
+ 290
+ 530
+ 181
+ 26
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
diff --git a/cfg/gui/cfg_gui_main.py b/cfg/gui/cfg_gui_main.py
new file mode 100644
index 00000000..232bfacb
--- /dev/null
+++ b/cfg/gui/cfg_gui_main.py
@@ -0,0 +1,393 @@
+from pathlib import Path
+from PySide6.QtWidgets import QWidget, QApplication, QFileDialog, QTextEdit, QPushButton, QDateTimeEdit, QLabel, QCheckBox, QVBoxLayout, QSizePolicy, QDoubleSpinBox, QLayout, QMessageBox
+from PySide6.QtCore import QProcess, QDateTime
+from PySide6.QtGui import QTextCharFormat, QPixmap
+from cfg_gui_ui import Ui_Form
+import sys, re, xmltodict, datetime, threading
+import xml.etree.ElementTree as ET
+import os
+
+# TODO: Update master xml sc-x-cfg filename if modified in sc config (in progress)
+# TODO: disableButtons(), enableButtons() not working as intended due to the gnome-terminal thread handling the commands externally
+
+class cfg_gui(QWidget):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ self.ui = Ui_Form()
+ self.ui.setupUi(self)
+ self.setFixedSize(655, 655)
+ self.setWindowTitle("NOS3 Igniter - Version 0.0.1")
+ self.setWindowIcon(QPixmap(f'{os.path.dirname(os.path.abspath(__file__))}/resources/nos3_original.png'))
+
+ # globals
+ self.dateTimeEdit = QDateTimeEdit()
+ self.scConfigs = {} # Stores child configs {'index' : "filetext"}
+ self.prevButtonPressed = None # Tracks the last button pressed, used in buttonColor()
+ self.defaultStyleSheet = self.ui.pushButton_buildAll.styleSheet() # Saves default stylesheet to return button color to normal, buttonColor()
+ self.setup = 0 # Allows for switchConfig() to initially be called without calling saveText()
+ self.configNumTrack = 0 # Tracks the index of the previous SC config when switching to another index
+ self.defaultConfig = f'{os.path.dirname(os.path.abspath(__file__))}/../nos3-mission.xml'
+ self.config_path = self.defaultConfig
+
+ # Config Tab
+ self.ui.pushButton_browse.clicked.connect(self.browseConfig)
+ self.ui.pushButton_save.clicked.connect(lambda: self.saveXML("save"))
+ self.ui.pushButton_saveAs.clicked.connect(lambda: self.saveXML("saveAs"))
+ self.ui.spinBox_configNumber.valueChanged.connect(lambda: self.switchConfig(self.ui.spinBox_configNumber.value()))
+ pixmap = QPixmap(f'{os.path.dirname(os.path.abspath(__file__))}/resources/JSTAR-transparent_original.png')
+ self.ui.label_jstarLogo.setPixmap(pixmap)
+ pixmap = QPixmap(f'{os.path.dirname(os.path.abspath(__file__))}/resources/nos3_original.png')
+ self.ui.label_nos3Logo.setPixmap(pixmap)
+
+ # Build Tab
+ self.ui.pushButton_buildAll.clicked.connect(lambda: self.build("all", self.ui.pushButton_buildAll))
+ self.ui.pushButton_cfgBuild.clicked.connect(lambda: self.build("config", self.ui.pushButton_cfgBuild))
+ self.ui.pushButton_fswBuild.clicked.connect(lambda: self.build("fsw", self.ui.pushButton_fswBuild))
+ self.ui.pushButton_gswBuild.clicked.connect(lambda: self.build("gsw", self.ui.pushButton_gswBuild))
+ self.ui.pushButton_simBuild.clicked.connect(lambda: self.build("sim", self.ui.pushButton_simBuild))
+ self.ui.pushButton_cleanAll.clicked.connect(lambda: self.clean("all", self.ui.pushButton_cleanAll))
+ self.ui.pushButton_fswClean.clicked.connect(lambda: self.clean("fsw", self.ui.pushButton_fswClean))
+ self.ui.pushButton_gswClean.clicked.connect(lambda: self.clean("gsw", self.ui.pushButton_gswClean))
+ self.ui.pushButton_simClean.clicked.connect(lambda: self.clean("sim", self.ui.pushButton_simClean))
+
+ # Launch Tab (Time Driver controls disabled)
+ #self.ui.pushButton_play.clicked.connect(lambda: self.startBashProcess(self.ui.textEdit_launchConsole, ["-lc", "echo '>> Starting NOS3 Time Driver'"]))
+ self.ui.pushButton_play.setDisabled(1)
+ self.ui.pushButton_stop.clicked.connect(lambda: self.gnome_terminal(self.ui.textEdit_launchConsole, "make stop"))
+ #self.ui.pushButton_pause.clicked.connect(lambda: self.startBashProcess(self.ui.textEdit_launchConsole, ["-lc", "echo '>> Pausing NOS3 Time Driver'"]))
+ self.ui.pushButton_pause.setDisabled(1)
+ self.ui.pushButton_launch.clicked.connect(lambda: self.gnome_terminal(self.ui.textEdit_launchConsole, "make launch"))
+ #self.ui.comboBox_run.currentIndexChanged.connect(self.run_ForUntil)
+ self.ui.comboBox_run.setDisabled(1)
+ self.ui.lineEdit_secondsEntry.setDisabled(1)
+
+ # Load Default Config
+ self.reloadConfig(self.defaultConfig)
+
+ # Replaces the textbox on launch tab with a date/time box and vice versa
+ def run_ForUntil(self):
+ index = self.ui.comboBox_run.currentIndex()
+ if index == 0:
+ self.ui.horizontalLayout_runForUntil.itemAt(1).widget().setParent(None)
+ self.ui.horizontalLayout_runForUntil.insertWidget(1, self.ui.lineEdit_secondsEntry)
+ self.ui.lineEdit_secondsEntry.setPlaceholderText("")
+ elif index == 1:
+ self.ui.horizontalLayout_runForUntil.itemAt(1).widget().setParent(None)
+ self.ui.horizontalLayout_runForUntil.insertWidget(1, self.ui.lineEdit_secondsEntry)
+ self.ui.lineEdit_secondsEntry.setPlaceholderText("Seconds")
+ elif index == 2:
+ self.ui.horizontalLayout_runForUntil.itemAt(1).widget().setParent(None)
+ self.currentTime = datetime.datetime.now()
+ self.dateTimeEdit.setMinimumDateTime(QDateTime(self.currentTime.year, self.currentTime.month, self.currentTime.day, self.currentTime.hour, self.currentTime.minute, self.currentTime.second, 0, 0))
+ self.ui.horizontalLayout_runForUntil.insertWidget(1, self.dateTimeEdit)
+
+ # Updates the currently saved xml dictionary (not actual xml file) for the currently selected spacecraft config when edited. TODO: change name of function
+ def saveText(self, layout:QLayout, config_value:int):
+ text = self.scConfigs[config_value]
+ filename = text.split('\n')[0]
+ childXml = xmltodict.parse(text.split('\n', 2)[2])
+
+ # TODO: change to dynamically pull apps/components from xml file or directory, but how?
+ applications = ['cf', 'ds', 'fm', 'lc', 'sc']
+ components = ['adcs', 'cam', 'css', 'eps', 'fss', 'gps', 'imu', 'mag', 'radio', 'rw', 'sample', 'st', 'syn', 'torquer']
+
+ i = 0
+ while layout.itemAt(i) != None:
+ widget = layout.itemAt(i).widget()
+
+ # Handle filename
+ if isinstance(widget, QTextEdit):
+ widget:QTextEdit
+ filename = widget.toPlainText()
+ if "Filename:" not in filename:
+ filename = f'Filename: {filename}'
+ if "Filename: " not in filename:
+ filename = f'Filename: {filename.split(":")[1]}'
+
+ # Handle checkboxes
+ elif isinstance(widget, QCheckBox):
+ widget:QCheckBox
+ text = widget.text().split(' ')[0]
+ if text in applications:
+ childXml['sc-1-config']['applications'][text]['enable'] = str(widget.isChecked()).lower()
+ elif text in components:
+ childXml['sc-1-config']['components'][text]['enable'] = str(widget.isChecked()).lower()
+ elif text == 'gui':
+ childXml['sc-1-config'][text]['enable'] = str(widget.isChecked()).lower()
+
+ # Handle orbits
+ elif isinstance(widget, QDoubleSpinBox):
+ widget:QDoubleSpinBox
+ prefix = widget.prefix().split(' ')[0]
+ childXml['sc-1-config']['orbit'][prefix] = str(widget.value())
+
+ # Increment index
+ i += 1
+
+ combined = filename + '\n\n' + xmltodict.unparse(childXml)
+ self.scConfigs[config_value] = combined
+
+ # Saves the master/child XML's edited in the GUI
+ def saveXML(self, saveType:str):
+ # saveType = "save" (overwrite) or "saveAs" (new)
+
+ if saveType == "saveAs":
+ savePath, _ = QFileDialog.getSaveFileName(None, 'Directory', './cfg')
+ elif saveType == "save":
+ savePath = self.config_path
+
+ # Grab master and save to xml
+ masterXml = xmltodict.parse(self.ui.textEdit_masterConfig.toPlainText())
+ self.convert2xml(masterXml, savePath)
+
+ # Now handle children
+ self.saveText(self.layout_, self.ui.spinBox_configNumber.value()-1)
+
+ for child in self.scConfigs:
+ text = str(self.scConfigs[child])
+ filename = text.split('\n')[0].split(' ')[1]
+ childXml = text.split('\n', 2)[2]
+ childXml = xmltodict.parse(childXml)
+
+ # save under same directory as masterXml using filename parsed from textEdit
+ self.convert2xml(childXml, savePath.rsplit('/', 1)[0]+f'/{filename}')
+
+ self.reloadConfig(self.config_path)
+
+ # Loads the child config into the Spacecraft Config textbox
+ def switchConfig(self, value:int):
+ # value : index of spacecraft config in the order listed in the master XML
+ # Note: Parameter indexing starts at 1
+
+ # save edits made to config before viewing next one
+ if self.setup == 1:
+ self.saveText(self.layout_, self.configNumTrack)
+ self.configNumTrack = value-1
+ else:
+ self.setup = 1
+
+ # setup layout to add item to
+ self.ui.scrollArea.setWidgetResizable(True)
+ self.ui.scrollAreaWidgetContents.setLayout(QVBoxLayout().layout())
+ self.layout_ = self.ui.scrollAreaWidgetContents.layout()
+ self.layout_.setSpacing(12)
+
+ # remove all items from SC Config window when switching index
+ while self.layout_.itemAt(0) != None:
+ child = self.layout_.itemAt(0).widget().setParent(None)
+
+ # Now parse the xml and convert to widgets
+ value = value-1
+ if value in self.scConfigs:
+ fileName = self.scConfigs[value].split('\n')[0]
+ childXML = self.scConfigs[value].split('\n')[2::]
+ childXML = ''.join(childXML)
+ childDict = xmltodict.parse(childXML)
+
+ # child = sc-xxx-cfg
+ for child in childDict:
+ configTag = QTextEdit()
+ configTag.setText((fileName))
+ configTag.setMinimumHeight(30)
+ self.layout_.addWidget(configTag)
+
+ # child2 = applications | components | gui | orbit
+ for child2 in childDict[child]:
+ tag = QLabel()
+ tag.setText(child2.upper()+": ")
+ format = QTextCharFormat()
+ format.setFontUnderline(True)
+ tag.setFont(format.font())
+ tag.setMinimumHeight(18)
+ self.layout_.addWidget(tag)
+
+ if child2 in ['applications', 'components']:
+
+ # child 3 = cf | ds | ... | adcs | cam | ...
+ for child3 in childDict[child][child2]:
+ enableTag = QCheckBox()
+ enableTag.setText(child3 + " enable ")
+ enableTag.setChecked(childDict[child][child2][child3]['enable'] == 'true')
+ enableTag.setMinimumHeight(18)
+ enableTag.sizePolicy().setVerticalPolicy(QSizePolicy.Expanding)
+ self.layout_.addWidget(enableTag)
+
+ elif child2 == 'gui':
+ enableTag = QCheckBox()
+ enableTag.setText(child2 + " enable ")
+ enableTag.setChecked(childDict[child][child2]['enable'] == 'true')
+ self.layout_.addWidget(enableTag)
+
+ elif child2 == 'orbit':
+
+ # child3 = tipoff_x/y/z
+ for child3 in childDict[child][child2]:
+ orbitSpinBox = QDoubleSpinBox()
+ orbitSpinBox.setMinimum(-99.00)
+ orbitSpinBox.setMaximum(99.00)
+ orbitSpinBox.setValue(float(childDict[child][child2][child3]))
+ orbitSpinBox.setPrefix(f'{child3} = ')
+ self.layout_.addWidget(orbitSpinBox)
+ else:
+ # No SC configs in master XML file, or selected a SC XML as master
+ tag = QLabel()
+ tag.setText("*ERROR*\n\nMake sure you chose a master configuration file\n\n*ERROR*")
+ self.layout_.addWidget(tag)
+
+ # Converts a dictionary to XML file, saved under the given filename/path
+ def convert2xml(self, attrDict:dict, fileName:str):
+ # ensure file is saved as xml
+ if fileName[-4::] != ".xml":
+ fileName += ".xml"
+
+ # unparse dictionary to xml
+ with open(fileName, "w") as f:
+ xmltodict.unparse(attrDict, f, pretty=True)
+ f.close()
+
+ # Opens file selection menu and calls parseXML() on the selected file
+ def browseConfig(self):
+
+ # Clear SC Config window when selecting a new master config
+ if "layout_" in self.__dict__:
+ while self.layout_.itemAt(0) != None:
+ self.layout_.itemAt(0).widget().setParent(None)
+
+ self.config_path, _ = QFileDialog.getOpenFileName(None, 'File', './cfg', "XML Files [ *.xml ]")
+ if self.config_path != "":
+ self.config_name = self.config_path.split("/")[-1]
+ self.ui.lineEdit_curConfig.setText(self.config_name)
+ self.parseXml(self.config_path)
+
+ # Reloads the whole config after clicking save, allows you to change "sc-x-cfg" xml file
+ def reloadConfig(self, config_path):
+ if "layout_" in self.__dict__:
+ while self.layout_.itemAt(0) != None:
+ self.layout_.itemAt(0).widget().setParent(None)
+
+ if config_path != "":
+ config_name = config_path.split("/")[-1]
+ self.ui.lineEdit_curConfig.setText(config_name)
+ self.parseXml(config_path)
+
+ self.ui.spinBox_configNumber.setValue(1)
+
+ # Parses Master and child XML files from the given file, updates text boxes accordingly
+ def parseXml(self, config_path):
+
+ # Read Master
+ with open(config_path, 'r') as f:
+ self.ui.textEdit_masterConfig.setText(f.read())
+ f.close()
+
+ # Parse number of SC and SC filenames from master
+ i = 1
+ self.sc_cfg_files = []
+ childDict = {}
+ self.master_root = ET.parse(config_path).getroot()
+ for child in self.master_root:
+ if child.tag == "number-spacecraft":
+ self.ui.spinBox_configNumber.setMaximum(int(child.text))
+ if re.match("sc-[0-9]+-cfg", child.tag):
+ childDict[child.tag] = child.text
+
+ # Check for duplicate xml's
+ if child.text in self.sc_cfg_files:
+ QMessageBox.critical(self, "Error", "Using duplicate Spacecraft Config Files, Changes will not be saved correctly")
+ print("Duplicate SC Config file")
+
+ self.sc_cfg_files.append(child.text)
+ i+=1
+
+ # Read Children
+ config_dir = str(config_path.rsplit('/', 1)[0])
+ for i, child in enumerate(childDict):
+ if Path(f'{config_dir}/{childDict[child]}').is_file():
+ filePath = f'{config_dir}/{childDict[child]}'
+ else:
+ raise FileNotFoundError(childDict[child])
+
+ with open(filePath, 'r') as f:
+ self.scConfigs[i] = f'Filename: {childDict[child]}\n\n{f.read()}'
+ f.close()
+
+ # Update Spacecraft Config Text to first SC config listed in master config
+ self.switchConfig(1)
+
+ # Test for gnome-terminal instead of bash, also uses startCommand() instead of start()
+ def gnome_terminal(self, textbox:QTextEdit, command:str):
+ process = QProcess()
+
+ # `read line` is to hold the terminal open after execution, allows errors to be seen
+ process.startCommand(f'gnome-terminal --tab -- bash -c "{command}; echo Done. Press ENTER to close.; read line" ')
+
+ process.readyReadStandardOutput.connect(lambda: textbox.append(process.readAllStandardOutput().data().decode()))
+ process.readyReadStandardError.connect(lambda: textbox.append(process.readAllStandardError().data().decode()))
+
+ process.waitForFinished(msecs=-1)
+ textbox.append(f'>> {command}...')
+
+ # Placeholder clean command
+ def clean(self, software:str, button:QPushButton):
+ textbox = self.ui.textEdit_buildConsole
+ if software == 'all':
+ command = f'make clean'
+ else:
+ command = f'make clean-{software}'
+
+ self.buttonColor(button)
+ t1 = threading.Thread(target=self.thread_gnome(textbox, button, command), name='t1')
+ t1.start()
+
+ # Placeholder build command, assumes make prep already ran, same with clean commands
+ def build(self, software:str, button:QPushButton):
+ textbox = self.ui.textEdit_buildConsole
+ if software == 'all':
+ command = f'make'
+ else:
+ command = f'make {software}'
+
+ self.buttonColor(button)
+ t1 = threading.Thread(target=self.thread_gnome(textbox, button, command), name='t1')
+ t1.start()
+
+ # Button/Bash function wrapper for threads
+ def thread_gnome(self, textbox:QTextEdit, button:QPushButton, command:str):
+ self.disableButtons(button)
+ self.gnome_terminal(textbox, command)
+ self.enableButtons(button)
+
+ # Changes the color of the most recently pressed button to green and the last pressed button to default
+ def buttonColor(self, button:QPushButton):
+ if self.prevButtonPressed is not None:
+ self.prevButtonPressed.setStyleSheet(self.defaultStyleSheet)
+ button.setStyleSheet('QPushButton {background-color: green;}')
+ self.prevButtonPressed = button
+
+ # Disable build/clean buttons while another is being ran (not working)
+ def disableButtons(self, button:QPushButton):
+ index = self.ui.gridLayout_buildCleanButtons.count()-1
+ while index >= 0:
+ widget = self.ui.gridLayout_buildCleanButtons.itemAt(index).widget()
+ if widget != button:
+ widget.setDisabled(1)
+ index -= 1
+
+ # Enable build/clean buttons after process is done running (not working)
+ def enableButtons(self, button:QPushButton):
+ index = self.ui.gridLayout_buildCleanButtons.count()-1
+ while index >= 0:
+ widget = self.ui.gridLayout_buildCleanButtons.itemAt(index).widget()
+ if widget != button:
+ widget.setEnabled(1)
+ index -= 1
+
+
+def main():
+ app = QApplication(sys.argv)
+ win = cfg_gui()
+ win.show()
+ sys.exit(app.exec())
+
+main()
\ No newline at end of file
diff --git a/cfg/gui/cfg_gui_ui.py b/cfg/gui/cfg_gui_ui.py
new file mode 100644
index 00000000..32b50d49
--- /dev/null
+++ b/cfg/gui/cfg_gui_ui.py
@@ -0,0 +1,431 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'cfg_gui.ui'
+##
+## Created by: Qt User Interface Compiler version 6.7.0
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
+ QMetaObject, QObject, QPoint, QRect,
+ QSize, QTime, QUrl, Qt)
+from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
+ QFont, QFontDatabase, QGradient, QIcon,
+ QImage, QKeySequence, QLinearGradient, QPainter,
+ QPalette, QPixmap, QRadialGradient, QTransform)
+from PySide6.QtWidgets import (QApplication, QComboBox, QFrame, QGridLayout,
+ QGroupBox, QHBoxLayout, QLabel, QLayout,
+ QLineEdit, QPushButton, QScrollArea, QSizePolicy,
+ QSpinBox, QTabWidget, QTextEdit, QVBoxLayout,
+ QWidget)
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(658, 655)
+ palette = QPalette()
+ brush = QBrush(QColor(0, 0, 0, 255))
+ brush.setStyle(Qt.SolidPattern)
+ palette.setBrush(QPalette.Active, QPalette.WindowText, brush)
+ brush1 = QBrush(QColor(255, 255, 255, 255))
+ brush1.setStyle(Qt.SolidPattern)
+ palette.setBrush(QPalette.Active, QPalette.Button, brush1)
+ palette.setBrush(QPalette.Active, QPalette.Light, brush1)
+ palette.setBrush(QPalette.Active, QPalette.Midlight, brush1)
+ brush2 = QBrush(QColor(127, 127, 127, 255))
+ brush2.setStyle(Qt.SolidPattern)
+ palette.setBrush(QPalette.Active, QPalette.Dark, brush2)
+ brush3 = QBrush(QColor(170, 170, 170, 255))
+ brush3.setStyle(Qt.SolidPattern)
+ palette.setBrush(QPalette.Active, QPalette.Mid, brush3)
+ palette.setBrush(QPalette.Active, QPalette.Text, brush)
+ palette.setBrush(QPalette.Active, QPalette.BrightText, brush1)
+ palette.setBrush(QPalette.Active, QPalette.ButtonText, brush)
+ palette.setBrush(QPalette.Active, QPalette.Base, brush1)
+ palette.setBrush(QPalette.Active, QPalette.Window, brush1)
+ palette.setBrush(QPalette.Active, QPalette.Shadow, brush)
+ palette.setBrush(QPalette.Active, QPalette.AlternateBase, brush1)
+ brush4 = QBrush(QColor(255, 255, 220, 255))
+ brush4.setStyle(Qt.SolidPattern)
+ palette.setBrush(QPalette.Active, QPalette.ToolTipBase, brush4)
+ palette.setBrush(QPalette.Active, QPalette.ToolTipText, brush)
+ brush5 = QBrush(QColor(0, 0, 0, 127))
+ brush5.setStyle(Qt.SolidPattern)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ palette.setBrush(QPalette.Active, QPalette.PlaceholderText, brush5)
+#endif
+ palette.setBrush(QPalette.Active, QPalette.Accent, brush1)
+ palette.setBrush(QPalette.Inactive, QPalette.WindowText, brush)
+ palette.setBrush(QPalette.Inactive, QPalette.Button, brush1)
+ palette.setBrush(QPalette.Inactive, QPalette.Light, brush1)
+ palette.setBrush(QPalette.Inactive, QPalette.Midlight, brush1)
+ palette.setBrush(QPalette.Inactive, QPalette.Dark, brush2)
+ palette.setBrush(QPalette.Inactive, QPalette.Mid, brush3)
+ palette.setBrush(QPalette.Inactive, QPalette.Text, brush)
+ palette.setBrush(QPalette.Inactive, QPalette.BrightText, brush1)
+ palette.setBrush(QPalette.Inactive, QPalette.ButtonText, brush)
+ palette.setBrush(QPalette.Inactive, QPalette.Base, brush1)
+ palette.setBrush(QPalette.Inactive, QPalette.Window, brush1)
+ palette.setBrush(QPalette.Inactive, QPalette.Shadow, brush)
+ palette.setBrush(QPalette.Inactive, QPalette.AlternateBase, brush1)
+ palette.setBrush(QPalette.Inactive, QPalette.ToolTipBase, brush4)
+ palette.setBrush(QPalette.Inactive, QPalette.ToolTipText, brush)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ palette.setBrush(QPalette.Inactive, QPalette.PlaceholderText, brush5)
+#endif
+ palette.setBrush(QPalette.Inactive, QPalette.Accent, brush1)
+ palette.setBrush(QPalette.Disabled, QPalette.WindowText, brush2)
+ palette.setBrush(QPalette.Disabled, QPalette.Button, brush1)
+ palette.setBrush(QPalette.Disabled, QPalette.Light, brush1)
+ palette.setBrush(QPalette.Disabled, QPalette.Midlight, brush1)
+ palette.setBrush(QPalette.Disabled, QPalette.Dark, brush2)
+ palette.setBrush(QPalette.Disabled, QPalette.Mid, brush3)
+ palette.setBrush(QPalette.Disabled, QPalette.Text, brush2)
+ palette.setBrush(QPalette.Disabled, QPalette.BrightText, brush1)
+ palette.setBrush(QPalette.Disabled, QPalette.ButtonText, brush2)
+ palette.setBrush(QPalette.Disabled, QPalette.Base, brush1)
+ palette.setBrush(QPalette.Disabled, QPalette.Window, brush1)
+ palette.setBrush(QPalette.Disabled, QPalette.Shadow, brush)
+ palette.setBrush(QPalette.Disabled, QPalette.AlternateBase, brush1)
+ palette.setBrush(QPalette.Disabled, QPalette.ToolTipBase, brush4)
+ palette.setBrush(QPalette.Disabled, QPalette.ToolTipText, brush)
+ brush6 = QBrush(QColor(127, 127, 127, 127))
+ brush6.setStyle(Qt.SolidPattern)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ palette.setBrush(QPalette.Disabled, QPalette.PlaceholderText, brush6)
+#endif
+ palette.setBrush(QPalette.Disabled, QPalette.Accent, brush1)
+ Form.setPalette(palette)
+ self.tabWidget = QTabWidget(Form)
+ self.tabWidget.setObjectName(u"tabWidget")
+ self.tabWidget.setGeometry(QRect(0, 0, 661, 661))
+ self.tabWidget.setTabShape(QTabWidget.TabShape.Rounded)
+ self.tab = QWidget()
+ self.tab.setObjectName(u"tab")
+ self.lineEdit_curConfig = QLineEdit(self.tab)
+ self.lineEdit_curConfig.setObjectName(u"lineEdit_curConfig")
+ self.lineEdit_curConfig.setGeometry(QRect(130, 20, 421, 26))
+ self.lineEdit_curConfig.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.lineEdit_curConfig.setReadOnly(True)
+ self.pushButton_browse = QPushButton(self.tab)
+ self.pushButton_browse.setObjectName(u"pushButton_browse")
+ self.pushButton_browse.setGeometry(QRect(550, 20, 94, 26))
+ self.label_curConfig = QLabel(self.tab)
+ self.label_curConfig.setObjectName(u"label_curConfig")
+ self.label_curConfig.setGeometry(QRect(10, 20, 121, 21))
+ self.groupBox_scConfig = QGroupBox(self.tab)
+ self.groupBox_scConfig.setObjectName(u"groupBox_scConfig")
+ self.groupBox_scConfig.setGeometry(QRect(10, 260, 631, 321))
+ self.horizontalLayoutWidget_6 = QWidget(self.groupBox_scConfig)
+ self.horizontalLayoutWidget_6.setObjectName(u"horizontalLayoutWidget_6")
+ self.horizontalLayoutWidget_6.setGeometry(QRect(0, 20, 631, 301))
+ self.horizontalLayout_6 = QHBoxLayout(self.horizontalLayoutWidget_6)
+ self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
+ self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0)
+ self.scrollArea = QScrollArea(self.horizontalLayoutWidget_6)
+ self.scrollArea.setObjectName(u"scrollArea")
+ sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.scrollArea.sizePolicy().hasHeightForWidth())
+ self.scrollArea.setSizePolicy(sizePolicy)
+ self.scrollArea.setAutoFillBackground(True)
+ self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
+ self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
+ self.scrollArea.setWidgetResizable(True)
+ self.scrollAreaWidgetContents = QWidget()
+ self.scrollAreaWidgetContents.setObjectName(u"scrollAreaWidgetContents")
+ self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 613, 68))
+ sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(0)
+ sizePolicy1.setHeightForWidth(self.scrollAreaWidgetContents.sizePolicy().hasHeightForWidth())
+ self.scrollAreaWidgetContents.setSizePolicy(sizePolicy1)
+ self.verticalLayout_3 = QVBoxLayout(self.scrollAreaWidgetContents)
+ self.verticalLayout_3.setObjectName(u"verticalLayout_3")
+ self.verticalLayout_3.setSizeConstraint(QLayout.SizeConstraint.SetDefaultConstraint)
+ self.scrollArea.setWidget(self.scrollAreaWidgetContents)
+
+ self.horizontalLayout_6.addWidget(self.scrollArea, 0, Qt.AlignmentFlag.AlignTop)
+
+ self.spinBox_configNumber = QSpinBox(self.groupBox_scConfig)
+ self.spinBox_configNumber.setObjectName(u"spinBox_configNumber")
+ self.spinBox_configNumber.setGeometry(QRect(150, -1, 48, 21))
+ self.spinBox_configNumber.setMinimum(1)
+ self.groupBox_masterConfig = QGroupBox(self.tab)
+ self.groupBox_masterConfig.setObjectName(u"groupBox_masterConfig")
+ self.groupBox_masterConfig.setGeometry(QRect(10, 60, 631, 181))
+ self.horizontalLayoutWidget_5 = QWidget(self.groupBox_masterConfig)
+ self.horizontalLayoutWidget_5.setObjectName(u"horizontalLayoutWidget_5")
+ self.horizontalLayoutWidget_5.setGeometry(QRect(0, 20, 631, 161))
+ self.horizontalLayout_5 = QHBoxLayout(self.horizontalLayoutWidget_5)
+ self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
+ self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
+ self.textEdit_masterConfig = QTextEdit(self.horizontalLayoutWidget_5)
+ self.textEdit_masterConfig.setObjectName(u"textEdit_masterConfig")
+ self.textEdit_masterConfig.setReadOnly(False)
+
+ self.horizontalLayout_5.addWidget(self.textEdit_masterConfig)
+
+ self.pushButton_save = QPushButton(self.tab)
+ self.pushButton_save.setObjectName(u"pushButton_save")
+ self.pushButton_save.setGeometry(QRect(220, 590, 94, 26))
+ self.pushButton_saveAs = QPushButton(self.tab)
+ self.pushButton_saveAs.setObjectName(u"pushButton_saveAs")
+ self.pushButton_saveAs.setGeometry(QRect(330, 590, 94, 26))
+ self.label_nos3Logo = QLabel(self.tab)
+ self.label_nos3Logo.setObjectName(u"label_nos3Logo")
+ self.label_nos3Logo.setGeometry(QRect(50, 585, 111, 41))
+ self.label_nos3Logo.setScaledContents(True)
+ self.label_jstarLogo = QLabel(self.tab)
+ self.label_jstarLogo.setObjectName(u"label_jstarLogo")
+ self.label_jstarLogo.setGeometry(QRect(480, 585, 131, 41))
+ self.label_jstarLogo.setScaledContents(True)
+ self.label_jstarLogo.setAlignment(Qt.AlignmentFlag.AlignLeading|Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter)
+ self.tabWidget.addTab(self.tab, "")
+ self.tab_2 = QWidget()
+ self.tab_2.setObjectName(u"tab_2")
+ self.groupBox_8 = QGroupBox(self.tab_2)
+ self.groupBox_8.setObjectName(u"groupBox_8")
+ self.groupBox_8.setGeometry(QRect(10, 120, 631, 491))
+ self.groupBox_8.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.groupBox_8.setFlat(False)
+ self.groupBox_8.setCheckable(False)
+ self.textEdit_buildConsole = QTextEdit(self.groupBox_8)
+ self.textEdit_buildConsole.setObjectName(u"textEdit_buildConsole")
+ self.textEdit_buildConsole.setGeometry(QRect(0, 20, 631, 471))
+ palette1 = QPalette()
+ palette1.setBrush(QPalette.Active, QPalette.Text, brush1)
+ palette1.setBrush(QPalette.Active, QPalette.Base, brush)
+ palette1.setBrush(QPalette.Inactive, QPalette.Text, brush1)
+ palette1.setBrush(QPalette.Inactive, QPalette.Base, brush)
+ self.textEdit_buildConsole.setPalette(palette1)
+ self.textEdit_buildConsole.setReadOnly(True)
+ self.frame_2 = QFrame(self.tab_2)
+ self.frame_2.setObjectName(u"frame_2")
+ self.frame_2.setGeometry(QRect(10, 20, 641, 81))
+ self.frame_2.setFrameShape(QFrame.Shape.StyledPanel)
+ self.frame_2.setFrameShadow(QFrame.Shadow.Raised)
+ self.frame = QFrame(self.frame_2)
+ self.frame.setObjectName(u"frame")
+ self.frame.setGeometry(QRect(79, 0, 561, 80))
+ self.frame.setFrameShape(QFrame.Shape.StyledPanel)
+ self.frame.setFrameShadow(QFrame.Shadow.Raised)
+ self.gridLayoutWidget_2 = QWidget(self.frame)
+ self.gridLayoutWidget_2.setObjectName(u"gridLayoutWidget_2")
+ self.gridLayoutWidget_2.setGeometry(QRect(0, 0, 561, 80))
+ self.gridLayout_buildCleanButtons = QGridLayout(self.gridLayoutWidget_2)
+ self.gridLayout_buildCleanButtons.setObjectName(u"gridLayout_buildCleanButtons")
+ self.gridLayout_buildCleanButtons.setContentsMargins(0, 0, 0, 0)
+ self.pushButton_cleanAll = QPushButton(self.gridLayoutWidget_2)
+ self.pushButton_cleanAll.setObjectName(u"pushButton_cleanAll")
+
+ self.gridLayout_buildCleanButtons.addWidget(self.pushButton_cleanAll, 1, 0, 1, 1)
+
+ self.pushButton_buildAll = QPushButton(self.gridLayoutWidget_2)
+ self.pushButton_buildAll.setObjectName(u"pushButton_buildAll")
+
+ self.gridLayout_buildCleanButtons.addWidget(self.pushButton_buildAll, 0, 0, 1, 1)
+
+ self.pushButton_fswBuild = QPushButton(self.gridLayoutWidget_2)
+ self.pushButton_fswBuild.setObjectName(u"pushButton_fswBuild")
+
+ self.gridLayout_buildCleanButtons.addWidget(self.pushButton_fswBuild, 0, 2, 1, 1)
+
+ self.pushButton_cfgBuild = QPushButton(self.gridLayoutWidget_2)
+ self.pushButton_cfgBuild.setObjectName(u"pushButton_cfgBuild")
+
+ self.gridLayout_buildCleanButtons.addWidget(self.pushButton_cfgBuild, 0, 1, 1, 1)
+
+ self.pushButton_simClean = QPushButton(self.gridLayoutWidget_2)
+ self.pushButton_simClean.setObjectName(u"pushButton_simClean")
+
+ self.gridLayout_buildCleanButtons.addWidget(self.pushButton_simClean, 1, 4, 1, 1)
+
+ self.pushButton_simBuild = QPushButton(self.gridLayoutWidget_2)
+ self.pushButton_simBuild.setObjectName(u"pushButton_simBuild")
+
+ self.gridLayout_buildCleanButtons.addWidget(self.pushButton_simBuild, 0, 4, 1, 1)
+
+ self.pushButton_gswBuild = QPushButton(self.gridLayoutWidget_2)
+ self.pushButton_gswBuild.setObjectName(u"pushButton_gswBuild")
+
+ self.gridLayout_buildCleanButtons.addWidget(self.pushButton_gswBuild, 0, 3, 1, 1)
+
+ self.pushButton_fswClean = QPushButton(self.gridLayoutWidget_2)
+ self.pushButton_fswClean.setObjectName(u"pushButton_fswClean")
+
+ self.gridLayout_buildCleanButtons.addWidget(self.pushButton_fswClean, 1, 2, 1, 1)
+
+ self.pushButton_gswClean = QPushButton(self.gridLayoutWidget_2)
+ self.pushButton_gswClean.setObjectName(u"pushButton_gswClean")
+
+ self.gridLayout_buildCleanButtons.addWidget(self.pushButton_gswClean, 1, 3, 1, 1)
+
+ self.frame_3 = QFrame(self.frame_2)
+ self.frame_3.setObjectName(u"frame_3")
+ self.frame_3.setGeometry(QRect(0, 0, 81, 41))
+ self.frame_3.setFrameShape(QFrame.Shape.StyledPanel)
+ self.frame_3.setFrameShadow(QFrame.Shadow.Raised)
+ self.verticalLayoutWidget = QWidget(self.frame_3)
+ self.verticalLayoutWidget.setObjectName(u"verticalLayoutWidget")
+ self.verticalLayoutWidget.setGeometry(QRect(0, 0, 81, 41))
+ self.verticalLayout = QVBoxLayout(self.verticalLayoutWidget)
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.label_4 = QLabel(self.verticalLayoutWidget)
+ self.label_4.setObjectName(u"label_4")
+ self.label_4.setAlignment(Qt.AlignmentFlag.AlignCenter)
+
+ self.verticalLayout.addWidget(self.label_4)
+
+ self.frame_4 = QFrame(self.frame_2)
+ self.frame_4.setObjectName(u"frame_4")
+ self.frame_4.setGeometry(QRect(0, 40, 81, 41))
+ self.frame_4.setFrameShape(QFrame.Shape.StyledPanel)
+ self.frame_4.setFrameShadow(QFrame.Shadow.Raised)
+ self.verticalLayoutWidget_2 = QWidget(self.frame_4)
+ self.verticalLayoutWidget_2.setObjectName(u"verticalLayoutWidget_2")
+ self.verticalLayoutWidget_2.setGeometry(QRect(0, 0, 81, 41))
+ self.verticalLayout_2 = QVBoxLayout(self.verticalLayoutWidget_2)
+ self.verticalLayout_2.setObjectName(u"verticalLayout_2")
+ self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.label_5 = QLabel(self.verticalLayoutWidget_2)
+ self.label_5.setObjectName(u"label_5")
+ self.label_5.setAlignment(Qt.AlignmentFlag.AlignCenter)
+
+ self.verticalLayout_2.addWidget(self.label_5)
+
+ self.tabWidget.addTab(self.tab_2, "")
+ self.tab_3 = QWidget()
+ self.tab_3.setObjectName(u"tab_3")
+ self.groupBox_control = QGroupBox(self.tab_3)
+ self.groupBox_control.setObjectName(u"groupBox_control")
+ self.groupBox_control.setGeometry(QRect(10, 10, 631, 611))
+ self.horizontalLayoutWidget = QWidget(self.groupBox_control)
+ self.horizontalLayoutWidget.setObjectName(u"horizontalLayoutWidget")
+ self.horizontalLayoutWidget.setGeometry(QRect(10, 570, 611, 31))
+ self.horizontalLayout = QHBoxLayout(self.horizontalLayoutWidget)
+ self.horizontalLayout.setSpacing(45)
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
+ self.pushButton_play = QPushButton(self.horizontalLayoutWidget)
+ self.pushButton_play.setObjectName(u"pushButton_play")
+ icon = QIcon()
+ icon.addFile(u"../../../../../../../../usr/share/icons/Humanity/actions/24/gtk-media-play-ltr.svg", QSize(), QIcon.Normal, QIcon.Off)
+ self.pushButton_play.setIcon(icon)
+
+ self.horizontalLayout.addWidget(self.pushButton_play)
+
+ self.pushButton_pause = QPushButton(self.horizontalLayoutWidget)
+ self.pushButton_pause.setObjectName(u"pushButton_pause")
+ icon1 = QIcon()
+ icon1.addFile(u"../../../../../../../../usr/share/icons/Humanity/actions/24/media-playback-pause.svg", QSize(), QIcon.Normal, QIcon.Off)
+ self.pushButton_pause.setIcon(icon1)
+
+ self.horizontalLayout.addWidget(self.pushButton_pause)
+
+ self.horizontalLayoutWidget_2 = QWidget(self.groupBox_control)
+ self.horizontalLayoutWidget_2.setObjectName(u"horizontalLayoutWidget_2")
+ self.horizontalLayoutWidget_2.setGeometry(QRect(10, 10, 611, 41))
+ self.horizontalLayout_2 = QHBoxLayout(self.horizontalLayoutWidget_2)
+ self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
+ self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.pushButton_launch = QPushButton(self.horizontalLayoutWidget_2)
+ self.pushButton_launch.setObjectName(u"pushButton_launch")
+
+ self.horizontalLayout_2.addWidget(self.pushButton_launch)
+
+ self.pushButton_stop = QPushButton(self.horizontalLayoutWidget_2)
+ self.pushButton_stop.setObjectName(u"pushButton_stop")
+
+ self.horizontalLayout_2.addWidget(self.pushButton_stop)
+
+ self.groupBox_9 = QGroupBox(self.groupBox_control)
+ self.groupBox_9.setObjectName(u"groupBox_9")
+ self.groupBox_9.setGeometry(QRect(10, 60, 611, 451))
+ self.groupBox_9.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.groupBox_9.setFlat(False)
+ self.groupBox_9.setCheckable(False)
+ self.textEdit_launchConsole = QTextEdit(self.groupBox_9)
+ self.textEdit_launchConsole.setObjectName(u"textEdit_launchConsole")
+ self.textEdit_launchConsole.setGeometry(QRect(0, 20, 611, 431))
+ palette2 = QPalette()
+ palette2.setBrush(QPalette.Active, QPalette.Text, brush1)
+ palette2.setBrush(QPalette.Active, QPalette.Base, brush)
+ palette2.setBrush(QPalette.Inactive, QPalette.Text, brush1)
+ palette2.setBrush(QPalette.Inactive, QPalette.Base, brush)
+ self.textEdit_launchConsole.setPalette(palette2)
+ self.textEdit_launchConsole.setReadOnly(True)
+ self.horizontalLayoutWidget_3 = QWidget(self.groupBox_control)
+ self.horizontalLayoutWidget_3.setObjectName(u"horizontalLayoutWidget_3")
+ self.horizontalLayoutWidget_3.setGeometry(QRect(190, 520, 261, 41))
+ self.horizontalLayout_runForUntil = QHBoxLayout(self.horizontalLayoutWidget_3)
+ self.horizontalLayout_runForUntil.setObjectName(u"horizontalLayout_runForUntil")
+ self.horizontalLayout_runForUntil.setContentsMargins(0, 0, 0, 0)
+ self.comboBox_run = QComboBox(self.horizontalLayoutWidget_3)
+ self.comboBox_run.addItem("")
+ self.comboBox_run.addItem("")
+ self.comboBox_run.addItem("")
+ self.comboBox_run.setObjectName(u"comboBox_run")
+
+ self.horizontalLayout_runForUntil.addWidget(self.comboBox_run)
+
+ self.lineEdit_secondsEntry = QLineEdit(self.horizontalLayoutWidget_3)
+ self.lineEdit_secondsEntry.setObjectName(u"lineEdit_secondsEntry")
+ self.lineEdit_secondsEntry.setAlignment(Qt.AlignmentFlag.AlignCenter)
+
+ self.horizontalLayout_runForUntil.addWidget(self.lineEdit_secondsEntry)
+
+ self.tabWidget.addTab(self.tab_3, "")
+
+ self.retranslateUi(Form)
+
+ self.tabWidget.setCurrentIndex(0)
+
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"Form", None))
+ self.lineEdit_curConfig.setPlaceholderText(QCoreApplication.translate("Form", u"None", None))
+ self.pushButton_browse.setText(QCoreApplication.translate("Form", u"Browse...", None))
+ self.label_curConfig.setText(QCoreApplication.translate("Form", u"Current Config:", None))
+ self.groupBox_scConfig.setTitle(QCoreApplication.translate("Form", u"Spacecraft Config", None))
+ self.groupBox_masterConfig.setTitle(QCoreApplication.translate("Form", u"Master Config", None))
+ self.pushButton_save.setText(QCoreApplication.translate("Form", u"Save", None))
+ self.pushButton_saveAs.setText(QCoreApplication.translate("Form", u"Save As...", None))
+ self.label_nos3Logo.setText("")
+ self.label_jstarLogo.setText("")
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QCoreApplication.translate("Form", u"Config", None))
+ self.groupBox_8.setTitle(QCoreApplication.translate("Form", u"Console Output", None))
+ self.pushButton_cleanAll.setText(QCoreApplication.translate("Form", u"All", None))
+ self.pushButton_buildAll.setText(QCoreApplication.translate("Form", u"All", None))
+ self.pushButton_fswBuild.setText(QCoreApplication.translate("Form", u"FSW", None))
+ self.pushButton_cfgBuild.setText(QCoreApplication.translate("Form", u"CFG", None))
+ self.pushButton_simClean.setText(QCoreApplication.translate("Form", u"SIM", None))
+ self.pushButton_simBuild.setText(QCoreApplication.translate("Form", u"SIM", None))
+ self.pushButton_gswBuild.setText(QCoreApplication.translate("Form", u"GSW", None))
+ self.pushButton_fswClean.setText(QCoreApplication.translate("Form", u"FSW", None))
+ self.pushButton_gswClean.setText(QCoreApplication.translate("Form", u"GSW", None))
+ self.label_4.setText(QCoreApplication.translate("Form", u"Build", None))
+ self.label_5.setText(QCoreApplication.translate("Form", u"Clean", None))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QCoreApplication.translate("Form", u"Build", None))
+ self.groupBox_control.setTitle("")
+ self.pushButton_play.setText(QCoreApplication.translate("Form", u"Play", None))
+ self.pushButton_pause.setText(QCoreApplication.translate("Form", u"Pause", None))
+ self.pushButton_launch.setText(QCoreApplication.translate("Form", u"Launch", None))
+ self.pushButton_stop.setText(QCoreApplication.translate("Form", u"Stop", None))
+ self.groupBox_9.setTitle(QCoreApplication.translate("Form", u"NOS3 Time Driver", None))
+ self.comboBox_run.setItemText(0, "")
+ self.comboBox_run.setItemText(1, QCoreApplication.translate("Form", u"Run For", None))
+ self.comboBox_run.setItemText(2, QCoreApplication.translate("Form", u"Run Until", None))
+
+ self.lineEdit_secondsEntry.setText("")
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), QCoreApplication.translate("Form", u"Launch", None))
+ # retranslateUi
+
diff --git a/cfg/gui/resources/JSTAR-transparent_original.png b/cfg/gui/resources/JSTAR-transparent_original.png
new file mode 100644
index 00000000..5a988078
Binary files /dev/null and b/cfg/gui/resources/JSTAR-transparent_original.png differ
diff --git a/cfg/gui/resources/nos3_original.png b/cfg/gui/resources/nos3_original.png
new file mode 100644
index 00000000..a4a9a98d
Binary files /dev/null and b/cfg/gui/resources/nos3_original.png differ
diff --git a/cfg/nos3_defs/arch_build_custom.cmake b/cfg/nos3_defs/arch_build_custom.cmake
index e2af60d2..a2919a52 100644
--- a/cfg/nos3_defs/arch_build_custom.cmake
+++ b/cfg/nos3_defs/arch_build_custom.cmake
@@ -28,18 +28,22 @@
add_compile_options(
#-std=c99 # Target the C99 standard (without gcc extensions)
#-pedantic # Issue all the warnings demanded by strict ISO C
- -Wall # Warn about most questionable operations
+ #-Wall # Warn about most questionable operations
#-Wstrict-prototypes # Warn about missing prototypes
- -Wwrite-strings # Warn if not treating string literals as "const"
- -Wpointer-arith # Warn about suspicious pointer operations
+ #-Wwrite-strings # Warn if not treating string literals as "const"
+ #-Wpointer-arith # Warn about suspicious pointer operations
#-Werror # Treat warnings as errors (code should be clean)
- -Wno-address-of-packed-member
+ #-Wno-address-of-packed-member
# Build Specific
-DBYTE_ORDER_LE
-D_LINUX_OS_
-D_DEFAULT_SOURCE
)
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wstrict-prototypes -pedantic -Werror")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wwrite-strings -Wpointer-arith -Wno-address-of-packed-member")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
+
if (CFE_SYSTEM_PSPNAME STREQUAL "nos-linux")
# find itc cmake module path
find_path(_ITC_CMAKE_MODULES_
diff --git a/cfg/nos3_defs/cpu1_cfe_es_startup.scr b/cfg/nos3_defs/cpu1_cfe_es_startup.scr
index 324d5265..7a21cddb 100644
--- a/cfg/nos3_defs/cpu1_cfe_es_startup.scr
+++ b/cfg/nos3_defs/cpu1_cfe_es_startup.scr
@@ -1,3 +1,4 @@
+CFE_LIB, crypto, Crypto_SC_Init, CRYPTO, 0, 0, 0x0, 0;
CFE_LIB, hwlib, hwlib_Init, HW_LIB, 0, 0, 0x0, 0;
CFE_LIB, io_lib, IO_LibInit, IO_LIB, 0, 0, 0x0, 0;
@@ -33,7 +34,6 @@ CFE_APP, generic_st, ST_AppMain, ST,
CFE_APP, syn, SYN_AppMain, SYN, 72, 32768, 0x0, 0;
CFE_LIB, cfs_lib, CFS_LibInit, CFS_LIB, 0, 0, 0x0, 0;
-CFE_LIB, crypto, Crypto_TC_Init, CRYPTO, 0, 0, 0x0, 0;
CFE_APP, cs, CS_AppMain, CS, 55, 16384, 0x0, 0;
CFE_APP, hk, HK_AppMain, HK, 63, 16384, 0x0, 0;
CFE_APP, hs, HS_AppMain, HS, 56, 16384, 0x0, 0;
diff --git a/cfg/nos3_defs/tables/ds_filter_tbl.c b/cfg/nos3_defs/tables/ds_filter_tbl.c
index c595d42a..de5a3afd 100644
--- a/cfg/nos3_defs/tables/ds_filter_tbl.c
+++ b/cfg/nos3_defs/tables/ds_filter_tbl.c
@@ -45,11 +45,12 @@
#include "cfe_msgids.h"
#include "ds_msgids.h"
+#include "sample_msgids.h"
+
/* #include "ci_lab_msgids.h" */
/* #include "to_lab_msgids.h" */
/* #include "cs_msgids.h" */
-/* #include "ds_msgids.h" */
/* #include "fm_msgids.h" */
/* #include "hk_msgids.h" */
/* #include "hs_msgids.h" */
@@ -196,11 +197,11 @@ DS_FilterTable_t DS_FilterTable = {
{DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED},
{DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED}}},
/* Packet Index 014 */
- {/* .MessageID = */ CFE_SB_MSGID_RESERVED,
+ {/* .MessageID = */ CFE_SB_MSGID_WRAP_VALUE(SAMPLE_REQ_HK_MID),
/* .Filter = */
{/* File table index, filter type, N, X, O */
- {DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED},
- {DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED},
+ {FILE_ALL_APP_HK_PKTS, DS_BY_COUNT, 1, 1, 0},
+ {FILE_ALL_APP_TLM_PKTS, DS_BY_COUNT, 1, 1, 0},
{DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED},
{DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED, DS_UNUSED}}},
/* Packet Index 015 */
diff --git a/cfg/nos3_defs/tables/sc_rts005.c b/cfg/nos3_defs/tables/sc_rts005.c
index e2da32b8..a1d85837 100644
--- a/cfg/nos3_defs/tables/sc_rts005.c
+++ b/cfg/nos3_defs/tables/sc_rts005.c
@@ -8,10 +8,9 @@
#include "sc_msg.h" /* defines SC message structures */
/* Command Includes */
-#include "generic_radio_msg.h"
-#include "generic_radio_msgids.h"
-#include "sample_msg.h"
-#include "sample_msgids.h"
+#include "cam_app.h"
+#include "generic_radio_app.h"
+#include "sample_app.h"
/* Custom table structure, modify as needed to add desired commands */
typedef struct
@@ -20,6 +19,8 @@ typedef struct
SAMPLE_Config_cmd_t cmd1;
SC_RtsEntryHeader_t hdr2;
GENERIC_RADIO_Proximity_cmd_t cmd2;
+ SC_RtsEntryHeader_t hdr3;
+ CAM_NoArgsCmd_t cmd3;
} SC_RtsStruct005_t;
/* Define the union to size the table correctly */
@@ -45,6 +46,10 @@ SC_RtsTable005_t SC_Rts005 = {
.cmd2.CmdHeader = CFE_MSG_CMD_HDR_INIT(GENERIC_RADIO_CMD_MID, SC_MEMBER_SIZE(cmd2), GENERIC_RADIO_PROXIMITY_CC, 0x00),
.cmd2.SCID = 0,
.cmd2.Payload = {0x18, 0xA9, 0xC0, 0x00, 0x00, 0x05, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00},
+
+ /* 3 - CAM NOOP */
+ .hdr3.TimeTag = 1,
+ .cmd3.CmdHeader = CFE_MSG_CMD_HDR_INIT(CAM_CMD_MID, SC_MEMBER_SIZE(cmd3), CAM_NOOP_CC, 0x00),
}
};
diff --git a/cfg/nos3_defs/targets.cmake b/cfg/nos3_defs/targets.cmake
index ddc442dd..b670344d 100644
--- a/cfg/nos3_defs/targets.cmake
+++ b/cfg/nos3_defs/targets.cmake
@@ -84,7 +84,7 @@ list(APPEND MISSION_GLOBAL_APPLIST
#
# Libraries
#
- #cryptolib
+ cryptolib
hwlib
io_lib
#
@@ -121,12 +121,17 @@ list(APPEND MISSION_GLOBAL_APPLIST
# Create Application Platform Include List
FOREACH(X ${MISSION_GLOBAL_APPLIST})
+ LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/mission_inc)
+ LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/fsw/mission_inc)
+ LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/inc)
LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/fsw/inc)
+ LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/platform_inc)
LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/fsw/platform_inc)
LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/platform_inc)
+ LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/public_inc)
LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/fsw/public_inc)
- LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/fsw/src)
LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/src)
+ LIST(APPEND APPLICATION_PLATFORM_INC_LIST ${${X}_MISSION_DIR}/fsw/src)
ENDFOREACH(X)
# FT_INSTALL_SUBDIR indicates where the black box test data files (lua scripts) should
diff --git a/cfg/nos3_defs/toolchain-amd64-linux-gnu.cmake b/cfg/nos3_defs/toolchain-amd64-linux-gnu.cmake
index a062e7fc..80f34130 100644
--- a/cfg/nos3_defs/toolchain-amd64-linux-gnu.cmake
+++ b/cfg/nos3_defs/toolchain-amd64-linux-gnu.cmake
@@ -30,5 +30,5 @@ add_definitions(-DBYTE_ORDER_LE)
add_definitions(-D_LINUX_OS_)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
-set(CI_TRANSPORT udp)
-set(TO_TRANSPORT udp)
+set(CI_TRANSPORT udp_tf)
+set(TO_TRANSPORT udp) # Note udp_tf used for Transfer Frames required for CryptoLib
diff --git a/cfg/sims/nos3-simulator.xml b/cfg/sims/nos3-simulator.xml
index a451c739..1e2a065b 100644
--- a/cfg/sims/nos3-simulator.xml
+++ b/cfg/sims/nos3-simulator.xml
@@ -132,11 +132,14 @@
SAMPLE_PROVIDER
+
@@ -158,8 +161,8 @@
GPS42SOCKET
fortytwo
4245
- 20
- 5
+ 30
+ 1
0
0
37
@@ -218,8 +221,8 @@
GENERIC_EPS_42_PROVIDER
fortytwo
4283
- 20
- 5
+ 30
+ 1
0
@@ -299,8 +302,8 @@
fortytwo
4277
4278
- 20
- 5
+ 30
+ 1
0
0
@@ -325,8 +328,8 @@
fortytwo
4377
4378
- 20
- 5
+ 30
+ 1
0
1
@@ -351,8 +354,8 @@
fortytwo
4477
4478
- 20
- 5
+ 30
+ 1
0
2
@@ -376,8 +379,8 @@
GENERIC_CSS_42_PROVIDER
fortytwo
4227
- 20
- 5
+ 30
+ 1
0
<42-css-scale-factor>1.042-css-scale-factor>
@@ -405,8 +408,8 @@
GENERIC_TORQUER_42_PROVIDER
fortytwo
4279
- 20
- 5
+ 30
+ 1
3
@@ -437,8 +440,8 @@
TRUTH42PROVIDER
fortytwo
9999
- 20
- 5
+ 30
+ 1
0
0
@@ -462,8 +465,8 @@
GENERIC_FSS_42_PROVIDER
fortytwo
4281
- 20
- 5
+ 30
+ 1
0
@@ -495,12 +498,19 @@
gsw
- cosmos
+
+ -->
+
+ cosmos
+ 8010
+ 6011
+
@@ -540,8 +550,8 @@
GENERIC_IMU_42_PROVIDER
fortytwo
4280
- 20
- 5
+ 30
+ 1
0
@@ -567,8 +577,8 @@
GENERIC_MAG_42_PROVIDER
fortytwo
4234
- 20
- 5
+ 30
+ 1
0
@@ -594,8 +604,8 @@
GENERIC_STAR_TRACKER_PROVIDER
fortytwo
4282
- 20
- 5
+ 30
+ 1
0
0
diff --git a/scripts/docker-compose.yml b/scripts/docker-compose.yml
deleted file mode 100755
index 953c6e72..00000000
--- a/scripts/docker-compose.yml
+++ /dev/null
@@ -1,112 +0,0 @@
-version: '3.3'
-services:
- nos_engine_server_standalone:
- volumes:
- - '$SIM_DIR:$SIM_DIR'
- network_mode: host
- image: nos3
- command: /usr/bin/nos_engine_server_standalone -f $SIM_BIN/nos_engine_server_config.json
- working_dir: $SIM_BIN
- tty: true
- nos-time-driver:
- volumes:
- - '$SIM_DIR:$SIM_DIR'
- network_mode: host
- image: nos3
- command: $SIM_BIN/nos-time-driver
- working_dir: $SIM_BIN
- depends_on:
- - nos_engine_server_standalone
- nos3-simulator-terminal:
- volumes:
- - '$SIM_DIR:$SIM_DIR'
- network_mode: host
- image: nos3
- command: $SIM_BIN/nos3-simulator-terminal
- working_dir: $SIM_BIN
- depends_on:
- - nos_engine_server_standalone
- nos3-cam-simulator:
- volumes:
- - '$SIM_DIR:$SIM_DIR'
- network_mode: host
- image: nos3
- command: $SIM_BIN/nos3-cam-simulator
- working_dir: $SIM_BIN
- depends_on:
- - nos_engine_server_standalone
- nos3-generic-reactionwheel-simulator:
- volumes:
- - '$SIM_DIR:$SIM_DIR'
- network_mode: host
- image: nos3
- command: $SIM_BIN/nos3-generic-reactionwheel-simulator
- working_dir: $SIM_BIN
- depends_on:
- - nos_engine_server_standalone
- nos3-gps-simulator:
- volumes:
- - '$SIM_DIR:$SIM_DIR'
- network_mode: host
- image: nos3
- command: $SIM_BIN/nos3-gps-simulator
- working_dir: $SIM_BIN
- depends_on:
- - nos_engine_server_standalone
- nos3-sample-simulator:
- volumes:
- - '$SIM_DIR:$SIM_DIR'
- network_mode: host
- image: nos3
- command: $SIM_BIN/nos3-sample-simulator
- working_dir: $SIM_BIN
- depends_on:
- - nos_engine_server_standalone
- truth42sim:
- volumes:
- - '$SIM_DIR:$SIM_DIR'
- network_mode: host
- image: nos3
- command: $SIM_BIN/nos3-single-simulator truth42sim
- working_dir: $SIM_BIN
- depends_on:
- - nos_engine_server_standalone
- fsw:
- volumes:
- - '$FSW_BIN:$FSW_BIN'
- network_mode: host
- image: nos3
- command: $FSW_BIN/core-cpu1 -R PO
- working_dir: $FSW_BIN
- stdin_open: true
- tty: true
- sysctls:
- - fs.mqueue.msg_max=500
- depends_on:
- - nos_engine_server_standalone
- fortytwo:
- volumes:
- - '/opt/nos3/42/NOS3InOut:/opt/nos3/42/NOS3InOut'
- - '/tmp/.X11-unix:/tmp/.X11-unix:ro'
- network_mode: host
- image: nos3
- command: /opt/nos3/42/42 NOS3InOut
- working_dir: /opt/nos3/42
- tty: true
- environment:
- - DISPLAY=$DISPLAY
- depends_on:
- - nos_engine_server_standalone
- cosmos:
- volumes:
- - '/home/nos3/Desktop/github-nos3/gsw/cosmos:/cosmos/cosmos'
- - '/home/nos3/Desktop/github-nos3/components/:/COMPONENTS'
- - '/tmp/.X11-unix:/tmp/.X11-unix:ro'
- network_mode: host
- image: ballaerospace/cosmos
- command: /bin/bash -c 'ruby Launcher -c nos3_launcher.txt --system nos3_system.txt && true' # true is necessary to avoid setpgrp error
- working_dir: /cosmos/cosmos
- tty: true
- environment:
- - DISPLAY=$DISPLAY
- - QT_X11_NO_MITSHM=1
diff --git a/scripts/docker_build_cryptolib.sh b/scripts/docker_build_cryptolib.sh
new file mode 100755
index 00000000..63126da2
--- /dev/null
+++ b/scripts/docker_build_cryptolib.sh
@@ -0,0 +1,31 @@
+#!/bin/bash -i
+#
+# Convenience script for NOS3 development
+# Use with the Dockerfile in the deployment repository
+# https://github.com/nasa-itc/deployment
+#
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+source $SCRIPT_DIR/env.sh
+
+# Check that local NOS3 directory exists
+if [ ! -d $USER_NOS3_DIR ]; then
+ echo ""
+ echo " Need to run make prep first!"
+ echo ""
+ exit 1
+fi
+
+# Check that configure build directory exists
+if [ ! -d $BASE_DIR/cfg/build ]; then
+ echo ""
+ echo " Need to run make config first!"
+ echo ""
+ exit 1
+fi
+
+# Make ground software build directory
+mkdir -p $BASE_DIR/gsw/build
+
+# Build
+$DFLAGS_CPUS -v $BASE_DIR:$BASE_DIR --name "nos_build_cryptolib" -w $BASE_DIR $DBOX make -j$NUM_CPUS build-cryptolib
diff --git a/scripts/checkout.sh b/scripts/docker_checkout.sh
similarity index 81%
rename from scripts/checkout.sh
rename to scripts/docker_checkout.sh
index 7b6d80b2..92c716f8 100755
--- a/scripts/checkout.sh
+++ b/scripts/docker_checkout.sh
@@ -21,11 +21,10 @@ echo ""
# Replace `--tab` with `--window-with-profile=KeepOpen` once you've created this gnome-terminal profile manually
#echo "42..."
-#cd /opt/nos3/42/
-#rm -rf NOS3InOut
-#cp -r $BASE_DIR/sims/cfg/InOut /opt/nos3/42/NOS3InOut
+#rm -rf $USER_NOS3_DIR/42/NOS3InOut
+#cp -r $BASE_DIR/cfg/build/InOut $USER_NOS3_DIR/42/NOS3InOut
#xhost +local:*
-#gnome-terminal --window-with-profile=KeepOpen --title="42" -- $DFLAGS -e DISPLAY=$DISPLAY -v /opt/nos3/42/NOS3InOut:/opt/nos3/42/NOS3InOut -v /tmp/.X11-unix:/tmp/.X11-unix:ro --name $SC_NUM"_fortytwo" -h fortytwo --network=$SC_NETNAME -w /opt/nos3/42 -t $DBOX /opt/nos3/42/42 NOS3InOut
+#gnome-terminal --tab --title=$SC_NUM" - 42" -- $DFLAGS -e DISPLAY=$DISPLAY -v $USER_NOS3_DIR:$USER_NOS3_DIR -v /tmp/.X11-unix:/tmp/.X11-unix:ro --name $SC_NUM"_fortytwo" -h fortytwo --network=$SC_NETNAME -w $USER_NOS3_DIR/42 -t $DBOX $USER_NOS3_DIR/42/42 NOS3InOut
#echo ""
echo "NOS Core..."
@@ -48,6 +47,7 @@ gnome-terminal --tab --title="Generic Star Tracker" -- $DFLAGS -v $SIM_DIR:$SIM_
# Rename for your checkout under test to allow checkout
gnome-terminal --tab --title="FPrime" -- $DFLAGS -v $BASE_DIR:$BASE_DIR --name $SC_NUM"_sample_checkout" --network=$SC_NETNAME -w $BASE_DIR $DBOX ./scripts/fsw_fprime_launch.sh
+#gnome-terminal --title="Sample Checkout" -- $DFLAGS -v $BASE_DIR:$BASE_DIR --name $SC_NUM"_sample_checkout" --network=$SC_NETNAME -w $BASE_DIR $DBOX ./components/sample/support/build/sample_checkout
echo ""
diff --git a/scripts/docker_launch.sh b/scripts/docker_launch.sh
index 5243c866..5d1caec7 100755
--- a/scripts/docker_launch.sh
+++ b/scripts/docker_launch.sh
@@ -101,6 +101,10 @@ do
# Debugging
# Replace `--tab` with `--window-with-profile=KeepOpen` once you've created this gnome-terminal profile manually
+ echo $SC_NUM " - CryptoLib..."
+ gnome-terminal --tab --title=$SC_NUM" - CryptoLib" -- $DFLAGS -v $BASE_DIR:$BASE_DIR --name $SC_NUM"_cryptolib" --network=$SC_NETNAME --network-alias=cryptolib -w $BASE_DIR/gsw/build $DBOX ./support/standalone
+ echo ""
+
echo $SC_NUM " - Simulators..."
cd $SIM_BIN
gnome-terminal --tab --title=$SC_NUM" - NOS Engine Server" -- $DFLAGS -v $SIM_DIR:$SIM_DIR --name $SC_NUM"_nos_engine_server" -h nos_engine_server --network=$SC_NETNAME -w $SIM_BIN $DBOX /usr/bin/nos_engine_server_standalone -f $SIM_BIN/nos_engine_server_config.json
@@ -126,9 +130,6 @@ do
gnome-terminal --tab --title=$SC_NUM" - Sample Sim" -- $DFLAGS -v $SIM_DIR:$SIM_DIR --name $SC_NUM"_sample_sim" --network=$SC_NETNAME -w $SIM_BIN $DBOX ./nos3-single-simulator $SC_CFG_FILE sample_sim
gnome-terminal --tab --title=$SC_NUM" - StarTrk Sim" -- $DFLAGS -v $SIM_DIR:$SIM_DIR --name $SC_NUM"_startrk_sim" --network=$SC_NETNAME -w $SIM_BIN $DBOX ./nos3-single-simulator $SC_CFG_FILE generic_star_tracker_sim
gnome-terminal --tab --title=$SC_NUM" - Torquer Sim" -- $DFLAGS -v $SIM_DIR:$SIM_DIR --name $SC_NUM"_torquer_sim" --network=$SC_NETNAME -w $SIM_BIN $DBOX ./nos3-single-simulator $SC_CFG_FILE generic_torquer_sim
-
- # Note: Can keep open if desired after a new gnome-profile is manually created
- #gnome-terminal --window-with-profile=KeepOpen --tab --title=$SC_NUM" - Sample Sim" -- $DFLAGS -v $SIM_DIR:$SIM_DIR --name $SC_NUM"_sample_sim" --network=$SC_NETNAME -w $SIM_BIN $DBOX ./nos3-single-simulator $SC_CFG_FILE sample_sim
echo ""
done
diff --git a/scripts/env.sh b/scripts/env.sh
index c077a426..f99dc99e 100755
--- a/scripts/env.sh
+++ b/scripts/env.sh
@@ -41,7 +41,7 @@ OPENC3_PATH=$OPENC3_DIR/openc3.sh
DNETWORK="docker network"
#fi
-#DBOX="ivvitc/nos3-64:20240306"
+#DBOX="ivvitc/nos3-64:20240430"
DBOX="ivvitc/nos3-64:fprime"
# Debugging
diff --git a/scripts/gsw_cosmos_build.sh b/scripts/gsw_cosmos_build.sh
index 53085664..84d591ac 100755
--- a/scripts/gsw_cosmos_build.sh
+++ b/scripts/gsw_cosmos_build.sh
@@ -7,14 +7,11 @@ CFG_BUILD_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd
SCRIPT_DIR=$CFG_BUILD_DIR/../../scripts
source $SCRIPT_DIR/env.sh
-# Debugging
-#echo "Script directory = " $SCRIPT_DIR
-#echo "Base directory = " $BASE_DIR
-#exit
-
-#echo "Make /tmp folders..."
-#mkdir /tmp/data 2> /dev/null
-#mkdir /tmp/data/hk 2> /dev/null
-#mkdir /tmp/uplink 2> /dev/null
-
echo "COSMOS build..."
+mkdir $GSW_DIR/COMPONENTS 2> /dev/null
+rm -r $GSW_DIR/COMPONENTS/* 2> /dev/null
+for i in $(find $BASE_DIR/components/ -name "gsw" -type d)
+do
+ #echo "$i"
+ cp -r $i/* $GSW_DIR/COMPONENTS/
+done
diff --git a/scripts/igniter_launch.sh b/scripts/igniter_launch.sh
new file mode 100755
index 00000000..bbe225d1
--- /dev/null
+++ b/scripts/igniter_launch.sh
@@ -0,0 +1,13 @@
+#!/bin/bash -i
+#
+# Convenience script for NOS# development
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+source $SCRIPT_DIR/env.sh
+echo ""
+echo ""
+
+cd $BASE_DIR
+python3 $BASE_DIR/cfg/gui/cfg_gui_main.py &
+echo ""
+echo ""
\ No newline at end of file
diff --git a/scripts/prepare.sh b/scripts/prepare.sh
index fd9942cc..eb492703 100755
--- a/scripts/prepare.sh
+++ b/scripts/prepare.sh
@@ -27,63 +27,39 @@ mkdir $USER_NOS3_DIR/42 2> /dev/null
echo ""
echo ""
-# while read_xml; do
-# if [[ $ENTITY = "fsw" ]]; then
-# FLIGHT_SOFTWARE=$CONTENT
-# break
-# fi
-# done < ./cfg/nos3-mission.xml
-
-# echo "Using Flight Software: ${FLIGHT_SOFTWARE}"
-# echo ""
-# echo ""
-
-# if [[ $FLIGHT_SOFTWARE = "fprime" ]] ; then
-
- echo "Preparing FPrime FSW"
- echo $DFLAGS_CPUS $DBOX
- $DFLAGS_CPUS -v $BASE_DIR:$BASE_DIR -v $USER_NOS3_DIR:$USER_NOS3_DIR --name "fprime_prepare" -w $BASE_DIR $DBOX ./scripts/prep_fprime.sh
-
- echo ""
- echo ""
-
-# echo "Prepare nos3 docker container..."
-# $DCALL image pull $DBOX
-# echo ""
-# echo ""
+echo "Preparing FPrime FSW"
+echo $DFLAGS_CPUS $DBOX
+$DFLAGS_CPUS -v $BASE_DIR:$BASE_DIR -v $USER_NOS3_DIR:$USER_NOS3_DIR --name "fprime_prepare" -w $BASE_DIR $DBOX ./scripts/prep_fprime.sh
+echo ""
+echo ""
-# echo "Prepare 42..."
-# cd $USER_NOS3_DIR
-# git clone https://github.com/nasa-itc/42.git --depth 1 -b nos3-main
-# cd $USER_NOS3_DIR/42
-# $DFLAGS_CPUS -v $BASE_DIR:$BASE_DIR -v $USER_NOS3_DIR:$USER_NOS3_DIR -w $USER_NOS3_DIR/42 --name "nos3_42_build" $DBOX make
-# echo ""
-# echo ""
-# fi
+echo "Clone openc3-cosmos into local user directory..."
+cd $USER_NOS3_DIR
+git clone https://github.com/nasa-itc/openc3-nos3.git --depth 1 -b main $USER_NOS3_DIR/cosmos
+echo ""
+echo ""
-# if [[ $FLIGHT_SOFTWARE = "cfs" ]] ; then
- echo "Clone openc3-cosmos into local user directory..."
- cd $USER_NOS3_DIR
- git clone https://github.com/nasa-itc/openc3-nos3.git --depth 1 -b main $USER_NOS3_DIR/cosmos
- git reset --hard
- echo ""
- echo ""
+echo "Prepare cosmos docker container..."
+$DCALL image pull ballaerospace/cosmos:4.5.0
+echo ""
+echo ""
- echo "Prepare cosmos docker container..."
- $DCALL image pull ballaerospace/cosmos:4.5.0
- echo ""
- echo ""
+echo "Prepare nos3 docker container..."
+$DCALL image pull $DBOX
+echo ""
+echo ""
- echo "Prepare nos3 docker container..."
- $DCALL image pull $DBOX
- echo ""
- echo ""
+echo "Prepare 42..."
+cd $USER_NOS3_DIR
+git clone https://github.com/nasa-itc/42.git --depth 1 -b nos3-main
+cd $USER_NOS3_DIR/42
+$DFLAGS_CPUS -v $BASE_DIR:$BASE_DIR -v $USER_NOS3_DIR:$USER_NOS3_DIR -w $USER_NOS3_DIR/42 --name "nos3_42_build" $DBOX make
+echo ""
+echo ""
- echo "Prepare 42..."
- cd $USER_NOS3_DIR
- git clone https://github.com/nasa-itc/42.git --depth 1 -b nos3-main
- cd $USER_NOS3_DIR/42
- $DFLAGS_CPUS -v $BASE_DIR:$BASE_DIR -v $USER_NOS3_DIR:$USER_NOS3_DIR -w $USER_NOS3_DIR/42 --name "nos3_42_build" $DBOX make
- echo ""
- echo ""
-# fi
+echo "Prepare Igniter..."
+pip3 install pyside6 xmltodict
+cd $BASE_DIR
+python3 $BASE_DIR/cfg/gui/cfg_gui_main.py &
+echo ""
+echo ""