├── deploy
├── windows
│ ├── resources
│ │ ├── info.rc
│ │ └── icon.ico
│ └── nsis
│ │ ├── readme.txt
│ │ ├── license.txt
│ │ └── setup.nsi
├── mac-osx
│ ├── icon.icns
│ └── info.plist
└── linux
│ ├── cansat-gss.png
│ └── cansat-gss.desktop
├── assets
├── translations
│ ├── en.qm
│ ├── es.qm
│ ├── translations.qrc
│ ├── en.ts
│ └── es.ts
├── images
│ ├── background.jpg
│ ├── images.qrc
│ ├── kaansat.svg
│ └── unaq.svg
├── fonts
│ ├── source-code-pro.ttf
│ └── fonts.qrc
├── icons
│ ├── fullscreen.svg
│ ├── fullscreen-exit.svg
│ ├── icons.qrc
│ ├── exit.svg
│ ├── csv.svg
│ ├── mexico.svg
│ ├── location.svg
│ └── united-states.svg
└── qml
│ ├── qml.qrc
│ ├── Components
│ ├── Terminal.qml
│ ├── DataLabel.qml
│ ├── GPS.qml
│ └── DataGrid.qml
│ ├── Modules
│ └── Dashboard.qml
│ ├── main.qml
│ └── UI.qml
├── README.md
├── LICENSE.md
├── src
├── AppInfo.h
├── AppQuiter.h
├── crc32.h
├── Translator.h
├── Constants.h
├── Translator.cpp
├── main.cpp
├── SerialManager.h
├── crc32.c
├── DataParser.h
├── SerialManager.cpp
└── DataParser.cpp
└── CanSat-GSS.pro
/deploy/windows/resources/info.rc:
--------------------------------------------------------------------------------
1 | IDI_ICON1 ICON DISCARDABLE "icon.ico"
2 |
--------------------------------------------------------------------------------
/deploy/mac-osx/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kaan-Sat/CanSat-GSS-2019/HEAD/deploy/mac-osx/icon.icns
--------------------------------------------------------------------------------
/assets/translations/en.qm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kaan-Sat/CanSat-GSS-2019/HEAD/assets/translations/en.qm
--------------------------------------------------------------------------------
/assets/translations/es.qm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kaan-Sat/CanSat-GSS-2019/HEAD/assets/translations/es.qm
--------------------------------------------------------------------------------
/assets/images/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kaan-Sat/CanSat-GSS-2019/HEAD/assets/images/background.jpg
--------------------------------------------------------------------------------
/deploy/linux/cansat-gss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kaan-Sat/CanSat-GSS-2019/HEAD/deploy/linux/cansat-gss.png
--------------------------------------------------------------------------------
/assets/fonts/source-code-pro.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kaan-Sat/CanSat-GSS-2019/HEAD/assets/fonts/source-code-pro.ttf
--------------------------------------------------------------------------------
/deploy/windows/resources/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kaan-Sat/CanSat-GSS-2019/HEAD/deploy/windows/resources/icon.ico
--------------------------------------------------------------------------------
/assets/fonts/fonts.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | source-code-pro.ttf
4 |
5 |
6 |
--------------------------------------------------------------------------------
/assets/translations/translations.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | en.qm
4 | es.qm
5 |
6 |
7 |
--------------------------------------------------------------------------------
/assets/images/images.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | kaansat.svg
4 | background.jpg
5 | unaq.svg
6 |
7 |
8 |
--------------------------------------------------------------------------------
/assets/icons/fullscreen.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/icons/fullscreen-exit.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/deploy/linux/cansat-gss.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Name=Ka'an Sat Ground Station Software
3 | Comment=Software for receiving and managing CanSat packets
4 | Exec=cansat-gss
5 | Terminal=false
6 | Type=Application
7 | StartupNotify=true
8 | Categories=Electronics;Engineering;Science;
9 | Icon=cansat-gss
10 |
--------------------------------------------------------------------------------
/assets/icons/icons.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | csv.svg
4 | location.svg
5 | exit.svg
6 | fullscreen-exit.svg
7 | fullscreen.svg
8 | mexico.svg
9 | united-states.svg
10 |
11 |
12 |
--------------------------------------------------------------------------------
/assets/qml/qml.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | UI.qml
4 | main.qml
5 | Components/Terminal.qml
6 | Components/DataGrid.qml
7 | Modules/Dashboard.qml
8 | Components/DataLabel.qml
9 | Components/GPS.qml
10 |
11 |
12 |
--------------------------------------------------------------------------------
/assets/icons/exit.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/deploy/windows/nsis/readme.txt:
--------------------------------------------------------------------------------
1 | STEPS
2 | -----
3 |
4 | * Assuming you have downloaded NSIS (http://nsis.sf.net)
5 |
6 | 1. Compile the application
7 | 2. Run "windeployqt"
8 | 3. Place the output files in a folder named "bin"
9 | 4. Create a new folder with the application name
10 | 5. Place the "bin" folder in the application folder
11 | 6. Place the files in the "goodies" folder in the application folder
12 | 7. Copy the script and place it one directory above the application folder
13 | 8. Copy the license.txt and place it one directory above the application folder
14 | 9. Compile the script, do not release it if you have any warning
--------------------------------------------------------------------------------
/assets/icons/csv.svg:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GSS-2019
2 |
3 | Software de Estación Terrena utilizado durante la competencia CanSat CUCEI 2019. El software esta desarrollado con Qt para proveer soporte multiplataforma y reducir las dependencias durante una eventual instalación.
4 |
5 | ## Compilación
6 |
7 | Para compilar el proyecto, se necesita descargar e instalar [Qt](https://qt.io/download). Una vez que se haya instalado Qt, abra el archivo `CanSat-GSS.pro` en Qt Creator, seleccione el kit apropiado y presione el botón de compilar.
8 |
9 | Alternativamente, abra una terminal (Linux/macOS) y ejecute los siguientes comandos:
10 |
11 | mkdir build
12 | cd build
13 | qmake ../
14 | make -j4
15 |
16 | ## Autores
17 |
18 | - [Alex Spataru](https://github.com/alex-spataru)
19 |
20 | ## Licencia
21 |
22 | Este proyecto esta distribuido bajo los terminos y condiciones de la licencia MIT, para más información, haga clic [aquí](LICENSE.md).
23 |
--------------------------------------------------------------------------------
/deploy/mac-osx/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | cansat-gss
9 | CFBundleGetInfoString
10 | Copyright © 2018-2019 Ka'an Sat
11 | CFBundleIconFile
12 | icon
13 | CFBundleIdentifier
14 | org.kaansat.gss
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | CanSat Ground Station Software
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | 2.0
23 | LSHasLocalizedDisplayName
24 |
25 | NSPrincipalClass
26 | NSApplication
27 | NSSupportsSuddenTermination
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # License
2 |
3 | Copyright (c) 2018-2020 the Ka'an Sat Team.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/deploy/windows/nsis/license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 Ka'an Sat
2 |
3 | Se concede permiso, libre de cargos, a cualquier persona que obtenga una copia
4 | de este software y de los archivos de documentación asociados (el "Software"),
5 | para utilizar el Software sin restricción, incluyendo sin limitación los
6 | derechos a usar, copiar, modificar, fusionar, publicar, distribuir,
7 | sublicenciar, y/o vender copias del Software, y a permitir a las personas a las
8 | que se les proporcione el Software a hacer lo mismo, sujeto a las siguientes
9 | condiciones:
10 |
11 | El aviso de copyright anterior y este aviso de permiso se incluirán en todas
12 | las copias o partes sustanciales del Software.
13 |
14 | EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O
15 | IMPLÍCITA, INCLUYENDO PERO NO LIMITADA A GARANTÍAS DE COMERCIALIZACIÓN,
16 | IDONEIDAD PARA UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. EN NINGÚN CASO LOS
17 | AUTORES O PROPIETARIOS DE LOS DERECHOS DE AUTOR SERÁN RESPONSABLES DE NINGUNA
18 | RECLAMACIÓN, DAÑOS U OTRAS RESPONSABILIDADES, YA SEA EN UNA ACCIÓN DE CONTRATO,
19 | AGRAVIO O CUALQUIER OTRO MOTIVO, DERIVADAS DE, FUERA DE O EN CONEXIÓN CON EL
20 | SOFTWARE O SU USO U OTRO TIPO DE ACCIONES EN EL SOFTWARE.
21 |
--------------------------------------------------------------------------------
/src/AppInfo.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #ifndef APP_INFO_H
24 | #define APP_INFO_H
25 |
26 | #define APP_NAME "CanSat Ground Station Software"
27 | #define APP_VERSION "2.0 RC"
28 | #define ORGANIZATION_NAME "Ka'an Sat"
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/assets/icons/mexico.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
47 |
--------------------------------------------------------------------------------
/src/AppQuiter.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #ifndef APPQUITER_H
24 | #define APPQUITER_H
25 |
26 | #include
27 | #include
28 |
29 | /**
30 | * Used to allow the QML app to force the application to quit (thus ignoring
31 | * the Window's attempt to block the application exit).
32 | */
33 | class AppQuiter : public QObject {
34 | Q_OBJECT
35 |
36 | public slots:
37 | void closeApplication() {
38 | qApp->quit();
39 | }
40 | };
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/assets/icons/location.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/assets/qml/Components/Terminal.qml:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import QtQuick 2.0
24 | import QtQuick.Layouts 1.0
25 | import QtQuick.Controls 2.4
26 | import QtQuick.Controls.Universal 2.0
27 |
28 | Item {
29 | //
30 | // Text display
31 | //
32 | TextArea {
33 | id: textArea
34 | readOnly: true
35 | color: "#72d5a3"
36 | font.pixelSize: 12
37 | anchors.fill: parent
38 | font.family: app.monoFont
39 | textFormat: Text.PlainText
40 | wrapMode: Text.WrapAtWordBoundaryOrAnywhere
41 | placeholderText: qsTr("No data received so far") + "..." + Translator.dummy
42 | }
43 |
44 | //
45 | // Display serial data
46 | //
47 | Connections {
48 | target: CSerialManager
49 | }
50 |
51 | //
52 | // Mouse area to stop user from interacting with console
53 | //
54 | MouseArea {
55 | enabled: true
56 | hoverEnabled: true
57 | anchors.fill: parent
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/assets/qml/Components/DataLabel.qml:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import QtQuick 2.0
24 | import QtQuick.Layouts 1.0
25 | import QtQuick.Controls 2.0
26 |
27 | RowLayout {
28 | property string title: ""
29 | property string units: ""
30 | property string dataset: ""
31 |
32 | spacing: app.spacing
33 | Layout.fillWidth: true
34 | Layout.fillHeight: true
35 |
36 | Item {
37 | Layout.fillWidth: true
38 | }
39 |
40 | Label {
41 | font.bold: true
42 | color: "#72d5a3"
43 | text: title + ":"
44 | font.pixelSize: 13
45 | Layout.fillWidth: false
46 | Layout.fillHeight: true
47 | font.family: app.monoFont
48 | horizontalAlignment: Label.AlignRight
49 | }
50 |
51 | Label {
52 | opacity: 0.85
53 | color: "#72d5a3"
54 | font.pixelSize: 13
55 | Layout.fillWidth: false
56 | Layout.fillHeight: true
57 | font.family: app.monoFont
58 | textFormat: Text.RichText
59 | horizontalAlignment: Label.AlignHCenter
60 | Layout.minimumWidth: font.pixelSize * 5
61 | text: CSerialManager.connected ? dataset + " " + units : "--.--"
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/assets/icons/united-states.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
54 |
--------------------------------------------------------------------------------
/src/crc32.h:
--------------------------------------------------------------------------------
1 | /*
2 | * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
3 | * code or tables extracted from it, as desired without restriction.
4 | *
5 | * First, the polynomial itself and its table of feedback terms. The
6 | * polynomial is
7 | * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
8 | *
9 | * Note that we take it "backwards" and put the highest-order term in
10 | * the lowest-order bit. The X^32 term is "implied"; the LSB is the
11 | * X^31 term, etc. The X^0 term (usually shown as "+1") results in
12 | * the MSB being 1
13 | *
14 | * Note that the usual hardware shift register implementation, which
15 | * is what we're using (we're merely optimizing it by doing eight-bit
16 | * chunks at a time) shifts bits into the lowest-order term. In our
17 | * implementation, that means shifting towards the right. Why do we
18 | * do it this way? Because the calculated CRC must be transmitted in
19 | * order from highest-order term to lowest-order term. UARTs transmit
20 | * characters in order from LSB to MSB. By storing the CRC this way
21 | * we hand it to the UART in the order low-byte to high-byte; the UART
22 | * sends each low-bit to hight-bit; and the result is transmission bit
23 | * by bit from highest- to lowest-order term without requiring any bit
24 | * shuffling on our part. Reception works similarly
25 | *
26 | * The feedback terms table consists of 256, 32-bit entries. Notes
27 | *
28 | * The table can be generated at runtime if desired; code to do so
29 | * is shown later. It might not be obvious, but the feedback
30 | * terms simply represent the results of eight shift/xor opera
31 | * tions for all combinations of data and CRC register values
32 | *
33 | * The values must be right-shifted by eight bits by the "updcrc
34 | * logic; the shift must be unsigned (bring in zeroes). On some
35 | * hardware you could probably optimize the shift in assembler by
36 | * using byte-swap instructions
37 | * polynomial $edb88320
38 | *
39 | *
40 | * CRC32 code derived from work by Gary S. Brown.
41 | */
42 |
43 | #ifndef CRC32_H
44 | #define CRC32_H
45 |
46 | #ifdef __cplusplus
47 | extern "C" {
48 | #endif
49 |
50 | #include
51 | #include
52 | #include
53 |
54 | extern uint32_t CRC32 (const void* buf, size_t size);
55 |
56 | #ifdef __cplusplus
57 | }
58 | #endif
59 |
60 | #endif
61 |
--------------------------------------------------------------------------------
/src/Translator.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Alex Spataru
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #ifndef _TRANSLATOR_H
24 | #define _TRANSLATOR_H
25 |
26 | #include
27 | #include
28 |
29 | #ifdef QT_QML_LIB
30 | #include
31 | #endif
32 |
33 | class Translator : public QObject
34 | {
35 | Q_OBJECT
36 |
37 | #ifdef QT_QML_LIB
38 | Q_PROPERTY (int language
39 | READ language
40 | WRITE setLanguage
41 | NOTIFY languageChanged)
42 | Q_PROPERTY (QString dummy
43 | READ dummyString
44 | NOTIFY languageChanged)
45 | Q_PROPERTY (QStringList availableLanguages
46 | READ availableLanguages
47 | CONSTANT)
48 | #endif
49 |
50 | signals:
51 | void languageChanged();
52 |
53 | public:
54 | explicit Translator();
55 |
56 | int language() const;
57 | int systemLanguage() const;
58 | QStringList availableLanguages() const;
59 |
60 | QString dummyString() const
61 | {
62 | return "";
63 | }
64 |
65 | static void DeclareQML()
66 | {
67 | #ifdef QT_QML_LIB
68 | qmlRegisterType ("Translator", 1, 0, "CTranslator");
69 | #endif
70 | }
71 |
72 | public slots:
73 | void setLanguage (const int language);
74 |
75 | private:
76 | int m_language;
77 | QTranslator m_translator;
78 | };
79 |
80 | #endif
81 |
--------------------------------------------------------------------------------
/src/Constants.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #ifndef CONSTANTS_H
24 | #define CONSTANTS_H
25 |
26 | #include
27 | #include
28 | #include
29 |
30 | #include
31 |
32 | /**
33 | * Defines what the last character of a packet generated by the
34 | * CanSAT should be.
35 | *
36 | * This is used to determine when we have received a full packet from the
37 | * CanSat.
38 | */
39 | static const QChar EOT_PRIMARY = QChar('\n');
40 |
41 | /**
42 | * Defines the next-to-last character of each packet.
43 | * Using two characters to separate packets gives us the following benefits:
44 | * - If we need to process more than one packet, we can do it by creating
45 | * an array of packets (using @c EOT_CHAR)
46 | * - We can detect and manage incomplete packets (using @c EOT_CHAR_SECONDARY)
47 | */
48 | static const QChar EOT_SECONDARY = QChar('\r');
49 |
50 | /**
51 | * Define data separator character
52 | */
53 | static const QChar DATA_SEPARATOR = QChar(',');
54 |
55 | /**
56 | * Defines the characters that each packet generated by the CanSat should
57 | * begin with. This information is used as an additional packet
58 | * validation method.
59 | */
60 | static const QByteArray HEADER_CODE = "KAANSATQRO";
61 |
62 | /**
63 | * Set maximum buffer size of 10 Kilobytes
64 | */
65 | static const int MAX_BUFFER_SIZE = 10 * 1024;
66 |
67 | /**
68 | * Packet validation options
69 | */
70 | static const bool ENABLE_CRC32 = false;
71 | static const bool ENABLE_PACKET_CHECK = true;
72 |
73 | /**
74 | * Rounds the given @a number to two decimal places
75 | */
76 | static inline double RoundDbl(const double n) {
77 | return floorl(n * 100.0) / 100.0;
78 | }
79 |
80 | #endif
81 |
--------------------------------------------------------------------------------
/src/Translator.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Alex Spataru
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #include
24 | #include
25 |
26 | #include "Translator.h"
27 |
28 | Translator::Translator() : m_language (0)
29 | {
30 | QSettings settings (qApp->organizationName(), qApp->applicationName());
31 | setLanguage (settings.value ("language", systemLanguage()).toInt());
32 | }
33 |
34 | int Translator::language() const
35 | {
36 | return m_language;
37 | }
38 |
39 | int Translator::systemLanguage() const
40 | {
41 | int lang = 0;
42 |
43 | switch (QLocale::system().language()) {
44 | case QLocale::English:
45 | lang = 0;
46 | break;
47 | case QLocale::Spanish:
48 | lang = 1;
49 | break;
50 | default:
51 | lang = 0;
52 | break;
53 | }
54 |
55 | return lang;
56 | }
57 |
58 | QStringList Translator::availableLanguages() const
59 | {
60 | return QStringList {
61 | "English",
62 | "Español"
63 | };
64 | }
65 |
66 | void Translator::setLanguage (const int language)
67 | {
68 | /* Get translation file base name */
69 | QString file;
70 | QLocale locale;
71 | switch (language) {
72 | case 0:
73 | file = "en";
74 | locale = QLocale (QLocale::English);
75 | break;
76 | case 1:
77 | file = "es";
78 | locale = QLocale (QLocale::Spanish);
79 | break;
80 | default:
81 | file = "en";
82 | locale = QLocale (QLocale::English);
83 | break;
84 | }
85 |
86 | /* Load translation file */
87 | qApp->removeTranslator (&m_translator);
88 | m_translator.load (locale, ":/translations/" + file + ".qm");
89 | qApp->installTranslator (&m_translator);
90 |
91 | /* Save settings */
92 | QSettings settings (qApp->organizationName(), qApp->applicationName());
93 | settings.setValue ("language", language);
94 |
95 | /* Update internal variables & notify application */
96 | m_language = language;
97 | emit languageChanged();
98 | }
99 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include "AppInfo.h"
29 | #include "AppQuiter.h"
30 | #include "DataParser.h"
31 | #include "Translator.h"
32 | #include "SerialManager.h"
33 |
34 | /**
35 | * @brief Entry-point function of the application
36 | *
37 | * @param argc argument count
38 | * @param argv argument string array
39 | *
40 | * @returns the exit status of the @c qApp event loop
41 | */
42 | int main(int argc, char** argv) {
43 | // Configure application flags
44 | QGuiApplication::setApplicationName(APP_NAME);
45 | QGuiApplication::setApplicationVersion(APP_VERSION);
46 | QGuiApplication::setOrganizationName(ORGANIZATION_NAME);
47 | QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
48 |
49 | // Create application controller
50 | QGuiApplication app(argc, argv);
51 |
52 | // Create application modules
53 | DataParser parser;
54 | AppQuiter appQuiter;
55 | Translator translator;
56 | QQmlApplicationEngine engine;
57 | QQuickStyle::setStyle("Universal");
58 |
59 | // Register QML modules
60 | Translator::DeclareQML();
61 |
62 | // Enable file logging for CSV and serial data
63 | parser.enableCsvLogging(true);
64 | SerialManager::getInstance()->enableFileLogging(true);
65 |
66 | // Configure QML engine context properties
67 | engine.rootContext()->setContextProperty("AppName", app.applicationName());
68 | engine.rootContext()->setContextProperty("AppCompany", app.organizationName());
69 | engine.rootContext()->setContextProperty("AppVersion", app.applicationVersion());
70 | engine.rootContext()->setContextProperty("CDataParser", &parser);
71 | engine.rootContext()->setContextProperty("CAppQuiter", &appQuiter);
72 | engine.rootContext()->setContextProperty ("Translator", &translator);
73 | engine.rootContext()->setContextProperty("CSerialManager", SerialManager::getInstance());
74 | engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
75 |
76 | // Exit if QML interface contains errors
77 | if (engine.rootObjects().isEmpty())
78 | return EXIT_FAILURE;
79 |
80 | // Enter application event loop
81 | return app.exec();
82 | }
83 |
--------------------------------------------------------------------------------
/src/SerialManager.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #ifndef SERIAL_MANAGER_H
24 | #define SERIAL_MANAGER_H
25 |
26 | #include
27 | #include
28 |
29 | class QSerialPort;
30 | class SerialManager : public QObject {
31 | Q_OBJECT
32 | Q_PROPERTY(bool connected
33 | READ connected
34 | NOTIFY connectionChanged)
35 | Q_PROPERTY(bool fileLoggingEnabled
36 | READ fileLoggingEnabled
37 | WRITE enableFileLogging
38 | NOTIFY fileLoggingEnabledChanged)
39 | Q_PROPERTY(QString receivedBytes
40 | READ receivedBytes
41 | NOTIFY packetReceived)
42 | Q_PROPERTY(QStringList serialDevices
43 | READ serialDevices
44 | NOTIFY serialDevicesChanged)
45 | Q_PROPERTY(int baudRate
46 | READ baudRate
47 | WRITE setBaudRate
48 | NOTIFY baudRateChanged)
49 |
50 | signals:
51 | void baudRateChanged();
52 | void connectionChanged();
53 | void serialDevicesChanged();
54 | void fileLoggingEnabledChanged();
55 | void packetLogged(const QString& data);
56 | void packetReceived(const QByteArray& data);
57 | void connectionError(const QString& deviceName);
58 | void connectionSuccess(const QString& deviceName);
59 |
60 | private:
61 | SerialManager();
62 | ~SerialManager();
63 |
64 | public:
65 | static SerialManager* getInstance();
66 |
67 | int baudRate() const;
68 | bool connected() const;
69 | bool fileLoggingEnabled() const;
70 |
71 | QString deviceName() const;
72 | QString receivedBytes() const;
73 | QStringList serialDevices() const;
74 |
75 | public slots:
76 | void openLogFile();
77 | void setBaudRate(const int rate);
78 | void startComm(const int device);
79 | void enableFileLogging(const bool enabled);
80 |
81 | private slots:
82 | void onDataReceived();
83 | void disconnectDevice();
84 | void configureLogFile();
85 | void refreshSerialDevices();
86 | void formatReceivedPacket(const QByteArray& data);
87 |
88 | private:
89 | bool packetLogAvailable() const;
90 | QString sizeStr(const qint64 bytes) const;
91 |
92 | private:
93 | int m_baudRate;
94 | QFile m_packetLog;
95 | qint64 m_dataLen;
96 | QByteArray m_buffer;
97 | QSerialPort* m_port;
98 | QStringList m_serialDevices;
99 |
100 | bool m_enableFileLogging;
101 | };
102 |
103 | #endif
104 |
--------------------------------------------------------------------------------
/assets/qml/Modules/Dashboard.qml:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import QtQuick 2.0
24 | import QtQuick.Layouts 1.0
25 | import QtQuick.Controls 2.4
26 | import QtQuick.Controls.Universal 2.0
27 |
28 | import "../Components"
29 |
30 | Rectangle {
31 | color: "transparent"
32 | border {
33 | width: 2
34 | color: "#646464"
35 | }
36 |
37 | //
38 | // Background rectangle
39 | //
40 | Rectangle {
41 | opacity: 0.75
42 | anchors.fill: parent
43 | color: Universal.background
44 | anchors.margins: parent.border.width
45 | }
46 |
47 | //
48 | // Main layout
49 | //
50 | RowLayout {
51 | spacing: app.spacing
52 |
53 | //
54 | // Anchors
55 | //
56 | anchors {
57 | fill: parent
58 | margins: app.spacing
59 | }
60 |
61 | //
62 | // GPS Map & Terminal
63 | //
64 | ColumnLayout {
65 | Layout.fillWidth: true
66 | Layout.fillHeight: true
67 | Layout.margins: app.spacing
68 |
69 | GroupBox {
70 | Layout.margins: 0
71 | Layout.fillWidth: true
72 | Layout.fillHeight: true
73 | font.family: app.monoFont
74 | title: "// " + qsTr("GPS Map & Raw Frame Data") + Translator.dummy
75 |
76 | background: Rectangle {
77 | color: "#000"
78 | opacity: 0.75
79 | border.width: 2
80 | anchors.fill: parent
81 | anchors.topMargin: 32
82 | border.color: "#646464"
83 | }
84 |
85 | ColumnLayout {
86 | anchors.fill: parent
87 | spacing: app.spacing
88 |
89 | GPS {
90 | Layout.fillWidth: true
91 | Layout.fillHeight: true
92 | }
93 |
94 | Terminal {
95 | opacity: 0.75
96 | Layout.margins: 0
97 | Layout.fillWidth: true
98 | Layout.minimumHeight: 196
99 | }
100 | }
101 | }
102 | }
103 |
104 | //
105 | // Sensor readings
106 | //
107 | DataGrid {
108 | Layout.fillWidth: false
109 | Layout.fillHeight: true
110 | Layout.margins: app.spacing
111 | }
112 | }
113 | }
114 |
115 |
--------------------------------------------------------------------------------
/CanSat-GSS.pro:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2018 Kaan-Sat
3 | #
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy
5 | # of this software and associated documentation files (the "Software"), to deal
6 | # in the Software without restriction, including without limitation the rights
7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | # copies of the Software, and to permit persons to whom the Software is
9 | # furnished to do so, subject to the following conditions:
10 | #
11 | # The above copyright notice and this permission notice shall be included in
12 | # all copies or substantial portions of the Software.
13 | #
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | # THE SOFTWARE.
21 | #
22 |
23 | #-------------------------------------------------------------------------------
24 | # Make options
25 | #-------------------------------------------------------------------------------
26 |
27 | UI_DIR = uic
28 | MOC_DIR = moc
29 | RCC_DIR = qrc
30 | OBJECTS_DIR = obj
31 |
32 | CONFIG += c++11
33 |
34 | #-------------------------------------------------------------------------------
35 | # Qt configuration
36 | #-------------------------------------------------------------------------------
37 |
38 | TEMPLATE = app
39 | TARGET = cansat-gss
40 |
41 | CONFIG += qtc_runnable
42 | CONFIG += resources_big
43 |
44 | QT += xml
45 | QT += svg
46 | QT += sql
47 | QT += core
48 | QT += quick
49 | QT += location
50 | QT += concurrent
51 | QT += serialport
52 | QT += positioning
53 | QT += quickcontrols2
54 |
55 | QTPLUGIN += qsvg
56 |
57 | #-------------------------------------------------------------------------------
58 | # Translations
59 | #-------------------------------------------------------------------------------
60 |
61 | TRANSLATIONS += \
62 | assets/translations/en.ts \
63 | assets/translations/es.ts
64 |
65 | #-------------------------------------------------------------------------------
66 | # Deploy options
67 | #-------------------------------------------------------------------------------
68 |
69 | win32* {
70 | RC_FILE = deploy/windows/resources/info.rc
71 | }
72 |
73 | macx* {
74 | ICON = deploy/mac-osx/icon.icns
75 | RC_FILE = deploy/mac-osx/icon.icns
76 | QMAKE_INFO_PLIST = deploy/mac-osx/info.plist
77 | QMAKE_POST_LINK = macdeployqt cansat-gss.app -qmldir=$$PWD/assets/qml
78 | }
79 |
80 | linux:!android {
81 | target.path = /usr/bin
82 | icon.path = /usr/share/pixmaps
83 | desktop.path = /usr/share/applications
84 | icon.files += deploy/linux/cansat-gss.png
85 | desktop.files += deploy/linux/cansat-gss.desktop
86 |
87 | INSTALLS += target desktop icon
88 | }
89 |
90 | #-------------------------------------------------------------------------------
91 | # Import source code
92 | #-------------------------------------------------------------------------------
93 |
94 | HEADERS += \
95 | src/AppInfo.h \
96 | src/DataParser.h \
97 | src/SerialManager.h \
98 | src/crc32.h \
99 | src/Constants.h \
100 | src/AppQuiter.h \
101 | src/Translator.h
102 |
103 | SOURCES += \
104 | src/DataParser.cpp \
105 | src/main.cpp \
106 | src/SerialManager.cpp \
107 | src/crc32.c \
108 | src/Translator.cpp
109 |
110 | DISTFILES += \
111 | assets/qml/Components/ComConsole.qml \
112 | assets/qml/Components/DataGrid.qml \
113 | assets/qml/Components/Overview.qml \
114 | assets/qml/Components/Terminal.qml \
115 | assets/qml/Modules/Configuration.qml \
116 | assets/qml/Modules/CsvData.qml \
117 | assets/qml/Modules/Logger.qml \
118 | assets/qml/main.qml \
119 | assets/qml/UI.qml \
120 | assets/qml/Modules/Dashboard.qml \
121 | assets/qml/Modules/GpsMap.qml \
122 | assets/qml/Components/DataLabel.qml
123 |
124 | RESOURCES += \
125 | assets/qml/qml.qrc \
126 | assets/images/images.qrc \
127 | assets/icons/icons.qrc \
128 | assets/fonts/fonts.qrc \
129 | assets/translations/translations.qrc
130 |
--------------------------------------------------------------------------------
/assets/qml/main.qml:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import QtQuick 2.0
24 | import QtQuick.Window 2.0
25 | import QtQuick.Controls 2.3
26 | import QtQuick.Controls.Material 2.0
27 | import QtQuick.Controls.Universal 2.0
28 |
29 | import Qt.labs.settings 1.0
30 |
31 | ApplicationWindow {
32 | id: app
33 |
34 | //
35 | // Application constants
36 | //
37 | readonly property int spacing: 8
38 | readonly property string invalidData: "--.--"
39 | readonly property string monoFont: {
40 | if (Qt.platform.os == "osx")
41 | return "Menlo"
42 |
43 | return loader.name
44 | }
45 |
46 | //
47 | // Window options
48 | //
49 | x: 100
50 | y: 100
51 | title: AppName
52 | minimumWidth: 1222
53 | minimumHeight: 580
54 | width: minimumWidth
55 | height: minimumHeight
56 |
57 | //
58 | // Show application window
59 | //
60 | Component.onCompleted: ui.fullscreen ? app.showFullScreen() :
61 | app.showNormal()
62 |
63 | //
64 | // Save window size on exit
65 | //
66 | Settings {
67 | property alias _x: app.x
68 | property alias _y: app.y
69 | property alias _w: app.width
70 | property alias _h: app.height
71 | property alias _l: ui.language
72 | property alias _f: ui.fullscreen
73 | }
74 |
75 | //
76 | // Ask user if he/she wants to exit app
77 | //
78 | onClosing: {
79 | close.accepted = false
80 | dialog.open()
81 | }
82 |
83 | //
84 | // Theme options
85 | //
86 | Material.theme: Material.Dark
87 | Universal.theme: Universal.Dark
88 | Universal.accent: Universal.Amber
89 |
90 | //
91 | // Background
92 | //
93 | background: Image {
94 | opacity: 0.72
95 | fillMode: Image.PreserveAspectCrop
96 | source: "qrc:/images/background.jpg"
97 | }
98 |
99 | //
100 | // Mono font loader
101 | //
102 | FontLoader {
103 | id: loader
104 | source: "qrc:/fonts/source-code-pro.ttf"
105 | }
106 |
107 | //
108 | // UI module
109 | //
110 | UI {
111 | id: ui
112 | anchors.fill: parent
113 | anchors.margins: app.spacing
114 | }
115 |
116 | //
117 | // Logo UNAQ
118 | //
119 | Image {
120 | sourceSize.width: 120
121 | source: "qrc:/images/unaq.svg"
122 |
123 | anchors {
124 | top: parent.top
125 | margins: app.spacing
126 | horizontalCenter: parent.horizontalCenter
127 | }
128 | }
129 |
130 | //
131 | // Connection status dialog
132 | //
133 | Dialog {
134 | id: dialog
135 |
136 | //
137 | // Only close the dialog when the user
138 | // presses on the 'OK' button
139 | //
140 | modal: true
141 | closePolicy: Dialog.NoAutoClose
142 | standardButtons: Dialog.Yes | Dialog.No
143 |
144 | //
145 | // Close the application when user clicks on 'yes' button
146 | //
147 | onAccepted: CAppQuiter.closeApplication()
148 |
149 | //
150 | // Center dialog on app window
151 | //
152 | x: (parent.width - width) / 2
153 | y: (parent.height - height) / 2
154 |
155 | //
156 | // Set min. width to 320 pixels
157 | //
158 | width: Math.max(implicitWidth, 320)
159 |
160 | //
161 | // Message description
162 | //
163 | title: qsTr("Exit confirmation") + Translator.dummy
164 | Label {
165 | anchors.fill: parent
166 | verticalAlignment: Qt.AlignTop
167 | horizontalAlignment: Qt.AlignLeft
168 | text: qsTr("Are you sure you want to exit %1?").arg(AppName) + Translator.dummy
169 | }
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/assets/images/kaansat.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
40 |
--------------------------------------------------------------------------------
/assets/translations/en.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Dashboard
6 |
7 | GPS Map & Raw Frame Data
8 |
9 |
10 |
11 |
12 | DataGrid
13 |
14 | Mission Status
15 |
16 |
17 |
18 | Mission Time
19 |
20 |
21 |
22 | Team ID
23 |
24 |
25 |
26 | Parachute Status
27 |
28 |
29 |
30 | Open
31 |
32 |
33 |
34 | Closed
35 |
36 |
37 |
38 | Checksum
39 |
40 |
41 |
42 | Sensor Readings
43 |
44 |
45 |
46 | Altitude
47 |
48 |
49 |
50 | Pressure
51 |
52 |
53 |
54 | Internal Temperature
55 |
56 |
57 |
58 | External Temperature
59 |
60 |
61 |
62 | Air Quality
63 |
64 |
65 |
66 | Carbon Monoxide
67 |
68 |
69 |
70 | Accelerometer
71 |
72 |
73 |
74 | Magnetometer
75 |
76 |
77 |
78 | GPS Data
79 |
80 |
81 |
82 | Latitude
83 |
84 |
85 |
86 | Longitude
87 |
88 |
89 |
90 | Satellites
91 |
92 |
93 |
94 | GPS Time
95 |
96 |
97 |
98 | Satellite Health
99 |
100 |
101 |
102 | Voltage
103 |
104 |
105 |
106 | Resets
107 |
108 |
109 |
110 | Packet Errors
111 |
112 |
113 |
114 | Packets Parsed
115 |
116 |
117 |
118 |
119 | DataParser
120 |
121 | CSV File Error
122 |
123 |
124 |
125 | Cannot open CSV file for writing!
126 |
127 |
128 |
129 |
130 | GPS
131 |
132 | Re-center
133 |
134 |
135 |
136 |
137 | SerialManager
138 |
139 | bytes
140 |
141 |
142 |
143 | Select Port
144 |
145 |
146 |
147 | KB
148 |
149 |
150 |
151 | MB
152 |
153 |
154 |
155 |
156 | Terminal
157 |
158 | No data received so far
159 |
160 |
161 |
162 |
163 | UI
164 |
165 | Warning
166 |
167 |
168 |
169 | Disconnected from "%1"
170 |
171 |
172 |
173 |
174 | main
175 |
176 | Exit confirmation
177 |
178 |
179 |
180 | Are you sure you want to exit %1?
181 |
182 |
183 |
184 |
185 |
--------------------------------------------------------------------------------
/deploy/windows/nsis/setup.nsi:
--------------------------------------------------------------------------------
1 | ;
2 | ; Copyright (c) 2017 Alex Spataru
3 | ;
4 | ; Se concede permiso, libre de cargos, a cualquier persona que obtenga una copia
5 | ; de este software y de los archivos de documentación asociados (el "Software"),
6 | ; para utilizar el Software sin restricción, incluyendo sin limitación los
7 | ; derechos a usar, copiar, modificar, fusionar, publicar, distribuir,
8 | ; sublicenciar, y/o vender copias del Software, y a permitir a las personas a
9 | ; las que se les proporcione el Software a hacer lo mismo, sujeto a las
10 | ; siguientes condiciones:
11 | ;
12 | ; El aviso de copyright anterior y este aviso de permiso se incluirán en todas
13 | ; las copias o partes sustanciales del Software.
14 | ;
15 | ; EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O
16 | ; IMPLÍCITA, INCLUYENDO PERO NO LIMITADA A GARANTÍAS DE COMERCIALIZACIÓN,
17 | ; IDONEIDAD PARA UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. EN NINGÚN CASO LOS
18 | ; AUTORES O PROPIETARIOS DE LOS DERECHOS DE AUTOR SERÁN RESPONSABLES DE NINGUNA
19 | ; RECLAMACIÓN, DAÑOS U OTRAS RESPONSABILIDADES, YA SEA EN UNA ACCIÓN DE
20 | ; CONTRATO, AGRAVIO O CUALQUIER OTRO MOTIVO, DERIVADAS DE, FUERA DE O EN
21 | ; CONEXIÓN CON EL SOFTWARE O SU USO U OTRO TIPO DE ACCIONES EN EL SOFTWARE.
22 | ;
23 |
24 | !include "MUI2.nsh"
25 | !include "LogicLib.nsh"
26 |
27 | !define APPNAME "Ground Station Software"
28 | !define UNIXNAME "cansat-gss"
29 | !define COMPANYNAME "Ka'an Sat"
30 | !define DESCRIPTION "Software de la estación terrena"
31 | !define VERSIONMAJOR 0
32 | !define VERSIONMINOR 1
33 | !define VERSIONBUILD 0
34 | !define ESTIMATED_SIZE 60000
35 | !define MUI_ABORTWARNING
36 | !define INSTALL_DIR "$PROGRAMFILES\${APPNAME}"
37 | !define MUI_FINISHPAGE_RUN
38 | !define MUI_FINISHPAGE_RUN_TEXT "Run ${APPNAME}"
39 | !define MUI_FINISHPAGE_RUN_FUNCTION "RunApplication"
40 | !define MUI_FINISHPAGE_LINK "Visitar página web"
41 | !define MUI_FINISHPAGE_LINK_LOCATION "http://unaq.com.mx"
42 | !define MUI_WELCOMEPAGE_TITLE "Bienvenido/a al instalador del ${APPNAME}!"
43 |
44 | !insertmacro MUI_PAGE_WELCOME
45 | !insertmacro MUI_PAGE_LICENSE "license.txt"
46 | !insertmacro MUI_PAGE_DIRECTORY
47 | !insertmacro MUI_PAGE_INSTFILES
48 | !insertmacro MUI_PAGE_FINISH
49 | !insertmacro MUI_UNPAGE_WELCOME
50 | !insertmacro MUI_UNPAGE_CONFIRM
51 | !insertmacro MUI_UNPAGE_INSTFILES
52 | !insertmacro MUI_LANGUAGE "Spanish"
53 |
54 | !macro VerifyUserIsAdmin
55 | UserInfo::GetAccountType
56 | pop $0
57 | ${If} $0 != "admin"
58 | messageBox mb_iconstop "Se requieren derechos de administrador!"
59 | setErrorLevel 740
60 | quit
61 | ${EndIf}
62 | !macroend
63 |
64 | Name "${APPNAME}"
65 | ManifestDPIAware true
66 | InstallDir "${INSTALL_DIR}"
67 | RequestExecutionLevel admin
68 | OutFile "${UNIXNAME}-${VERSIONMAJOR}.${VERSIONMINOR}${VERSIONBUILD}-setup.exe"
69 |
70 | Function .onInit
71 | setShellVarContext all
72 | !insertmacro VerifyUserIsAdmin
73 | FunctionEnd
74 |
75 | Section "${APPNAME} (required)" SecDummy
76 | SectionIn RO
77 | SetOutPath "${INSTALL_DIR}"
78 | File /r "${APPNAME}\*"
79 | DeleteRegKey HKCU "Software\${COMPANYNAME}\${APPNAME}"
80 | DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}"
81 |
82 | WriteUninstaller "${INSTALL_DIR}\uninstall.exe"
83 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayName" "${APPNAME}"
84 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "UninstallString" "${INSTALL_DIR}\uninstall.exe"
85 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "InstallLocation" "${INSTALL_DIR}"
86 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "Publisher" "${COMPANYNAME}"
87 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayIcon" "${INSTALL_DIR}\bin\${APPNAME}.exe"
88 | WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayVersion" ${VERSIONMAJOR}.${VERSIONMINOR}${VERSIONBUILD}
89 | WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMajor" ${VERSIONMAJOR}
90 | WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMinor" ${VERSIONMINOR}
91 | WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoModify" 1
92 | WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoRepair" 1
93 | WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "EstimatedSize" ${ESTIMATED_SIZE}
94 |
95 | SectionEnd
96 |
97 | Section "Start Menu Shortcuts"
98 | CreateShortCut "$SMPROGRAMS\${APPNAME}.lnk" "${INSTALL_DIR}\bin\${APPNAME}.exe" "" "${INSTALL_DIR}\bin\${APPNAME}.exe" 0
99 | SectionEnd
100 |
101 | Function RunApplication
102 | ExecShell "" "${INSTALL_DIR}\bin\${APPNAME}.exe"
103 | FunctionEnd
104 |
105 | Function un.onInit
106 | SetShellVarContext all
107 | MessageBox MB_OKCANCEL|MB_ICONQUESTION "Realmente quiere desinstalar ${APPNAME}?" IDOK next
108 | Abort
109 | next:
110 | !insertmacro VerifyUserIsAdmin
111 | FunctionEnd
112 |
113 | Section "Uninstall"
114 | RMDir /r "${INSTALL_DIR}"
115 | RMDir /r "$SMPROGRAMS\${APPNAME}.lnk"
116 | DeleteRegKey HKCU "Software\${COMPANYNAME}\${APPNAME}"
117 | DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}"
118 | SectionEnd
119 |
--------------------------------------------------------------------------------
/assets/translations/es.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Dashboard
6 |
7 | GPS Map & Raw Frame Data
8 | Mapa GPS y Datos de Trama
9 |
10 |
11 |
12 | DataGrid
13 |
14 | Mission Status
15 | Estado de la Misión
16 |
17 |
18 | Mission Time
19 | Tiempo de Misión
20 |
21 |
22 | Team ID
23 | ID de Equipo
24 |
25 |
26 | Parachute Status
27 | Estatus de Paracaídas
28 |
29 |
30 | Open
31 | Abierto
32 |
33 |
34 | Closed
35 | Cerrado
36 |
37 |
38 | Checksum
39 | Código de Verificación
40 |
41 |
42 | Sensor Readings
43 | Lecturas de Sensor
44 |
45 |
46 | Altitude
47 | Altitud
48 |
49 |
50 | Pressure
51 | Presión
52 |
53 |
54 | Internal Temperature
55 | Temperatura Interna
56 |
57 |
58 | External Temperature
59 | Temperatura Externa
60 |
61 |
62 | Air Quality
63 | Calidad del Aire
64 |
65 |
66 | Carbon Monoxide
67 | Monóxido de Carbono
68 |
69 |
70 | Accelerometer
71 | Acelerómetro
72 |
73 |
74 | Magnetometer
75 | Magnetómetro
76 |
77 |
78 | GPS Data
79 | Datos GPS
80 |
81 |
82 | Latitude
83 | Latitud
84 |
85 |
86 | Longitude
87 | Longitud
88 |
89 |
90 | Satellites
91 | Satélites
92 |
93 |
94 | GPS Time
95 | Tiempo GPS
96 |
97 |
98 | Satellite Health
99 | Estado del Satélite
100 |
101 |
102 | Voltage
103 | Voltaje
104 |
105 |
106 | Resets
107 | Reinicios
108 |
109 |
110 | Packet Errors
111 | Tramas Corruptas
112 |
113 |
114 | Packets Parsed
115 | Tramas Analizadas
116 |
117 |
118 |
119 | DataParser
120 |
121 | CSV File Error
122 | Error del archivo CSV
123 |
124 |
125 | Cannot open CSV file for writing!
126 | No se puede abrir el archivo CSV para escritura!
127 |
128 |
129 |
130 | GPS
131 |
132 | Re-center
133 | Centrar
134 |
135 |
136 |
137 | SerialManager
138 |
139 | bytes
140 |
141 |
142 |
143 | Select Port
144 | Seleccionar Puerto
145 |
146 |
147 | KB
148 |
149 |
150 |
151 | MB
152 |
153 |
154 |
155 |
156 | Terminal
157 |
158 | No data received so far
159 | No se han recibido datos hasta el momento
160 |
161 |
162 |
163 | UI
164 |
165 | Warning
166 | Advertencia
167 |
168 |
169 | Disconnected from "%1"
170 | Desconectado de "%1"
171 |
172 |
173 |
174 | main
175 |
176 | Exit confirmation
177 | Confirmación de Salida
178 |
179 |
180 | Are you sure you want to exit %1?
181 | ¿Estas seguro que quieres salir de %1?
182 |
183 |
184 |
185 |
--------------------------------------------------------------------------------
/src/crc32.c:
--------------------------------------------------------------------------------
1 | /*
2 | * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
3 | * code or tables extracted from it, as desired without restriction.
4 | *
5 | * First, the polynomial itself and its table of feedback terms. The
6 | * polynomial is
7 | * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
8 | *
9 | * Note that we take it "backwards" and put the highest-order term in
10 | * the lowest-order bit. The X^32 term is "implied"; the LSB is the
11 | * X^31 term, etc. The X^0 term (usually shown as "+1") results in
12 | * the MSB being 1
13 | *
14 | * Note that the usual hardware shift register implementation, which
15 | * is what we're using (we're merely optimizing it by doing eight-bit
16 | * chunks at a time) shifts bits into the lowest-order term. In our
17 | * implementation, that means shifting towards the right. Why do we
18 | * do it this way? Because the calculated CRC must be transmitted in
19 | * order from highest-order term to lowest-order term. UARTs transmit
20 | * characters in order from LSB to MSB. By storing the CRC this way
21 | * we hand it to the UART in the order low-byte to high-byte; the UART
22 | * sends each low-bit to hight-bit; and the result is transmission bit
23 | * by bit from highest- to lowest-order term without requiring any bit
24 | * shuffling on our part. Reception works similarly
25 | *
26 | * The feedback terms table consists of 256, 32-bit entries. Notes
27 | *
28 | * The table can be generated at runtime if desired; code to do so
29 | * is shown later. It might not be obvious, but the feedback
30 | * terms simply represent the results of eight shift/xor opera
31 | * tions for all combinations of data and CRC register values
32 | *
33 | * The values must be right-shifted by eight bits by the "updcrc
34 | * logic; the shift must be unsigned (bring in zeroes). On some
35 | * hardware you could probably optimize the shift in assembler by
36 | * using byte-swap instructions
37 | * polynomial $edb88320
38 | *
39 | *
40 | * CRC32 code derived from work by Gary S. Brown.
41 | */
42 |
43 | #include "crc32.h"
44 |
45 | static uint32_t crc32_tab[] = {
46 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
47 | 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
48 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
49 | 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
50 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
51 | 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
52 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
53 | 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
54 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
55 | 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
56 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
57 | 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
58 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
59 | 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
60 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
61 | 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
62 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
63 | 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
64 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
65 | 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
66 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
67 | 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
68 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
69 | 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
70 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
71 | 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
72 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
73 | 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
74 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
75 | 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
76 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
77 | 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
78 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
79 | 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
80 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
81 | 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
82 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
83 | 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
84 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
85 | 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
86 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
87 | 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
88 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
89 | };
90 |
91 | uint32_t CRC32 (const void* buf, size_t size)
92 | {
93 | assert (buf);
94 |
95 | const uint8_t* p;
96 | uint32_t crc = 0xFFFFFFFFUL;
97 |
98 | p = buf;
99 |
100 | while (size--)
101 | crc = crc32_tab [(crc ^ *p++) & 0xFF] ^ (crc >> 8);
102 |
103 | return crc ^ 0xFFFFFFFFUL;
104 | }
105 |
--------------------------------------------------------------------------------
/assets/qml/Components/GPS.qml:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import QtQuick 2.0
24 | import QtLocation 5.11
25 | import QtPositioning 5.11
26 | import QtQuick.Layouts 1.0
27 | import QtQuick.Controls 2.0
28 | import QtQuick.Controls.Universal 2.0
29 |
30 | import Qt.labs.settings 1.0
31 |
32 | ColumnLayout {
33 | spacing: app.spacing
34 | Component.onCompleted: centerMap()
35 |
36 | //
37 | // Real-time GPS coordinates components
38 | //
39 | property real latitude: CDataParser.gpsLatitude
40 | property real longitude: CDataParser.gpsLongitude
41 |
42 | //
43 | // Will be true if GPS coordinates are different from (0,0)
44 | //
45 | readonly property bool gpsWorking: latitude != 0 || longitude != 0
46 |
47 | //
48 | // Location of Queretaro
49 | //
50 | readonly property var qroCoordinates: QtPositioning.coordinate(20.5846129, -100.385372)
51 |
52 | //
53 | // Used to know if we need to center the map
54 | //
55 | property var oldCoordinates: QtPositioning.coordinate(0,0)
56 |
57 | //
58 | // Real-time position
59 | //
60 | readonly property var gpsCoordinates: QtPositioning.coordinate(latitude, longitude)
61 |
62 | //
63 | // Center map when connecting with CanSat
64 | //
65 | Connections {
66 | target: CDataParser
67 | onDataParsed: {
68 | if (oldCoordinates === QtPositioning.coordinate(0,0)) {
69 | map.center = gpsCoordinates
70 | oldCoordinates = gpsCoordinates
71 | }
72 | }
73 | } Connections {
74 | target: CSerialManager
75 | onConnectionSuccess: oldCoordinates = QtPositioning.coordinate(0,0)
76 | }
77 |
78 | //
79 | // Centers the map to Queretaro if the GPS is not working,
80 | // otherwise, centers the map to the CanSat's position
81 | //
82 | function centerMap() {
83 | // GPS not responding, go to QRO
84 | if (!gpsWorking)
85 | map.center = qroCoordinates
86 |
87 | // Show GPS position
88 | else
89 | map.center = gpsCoordinates
90 | }
91 |
92 | //
93 | // Save settings between runs
94 | //
95 | Settings {
96 | property alias mapType: mapTypeSelector.currentIndex
97 | }
98 |
99 | //
100 | // Controls
101 | //
102 | RowLayout {
103 | spacing: app.spacing
104 | Layout.fillWidth: true
105 |
106 | ComboBox {
107 | id: mapTypeSelector
108 | textRole: "description"
109 | Layout.fillWidth: true
110 | Layout.preferredWidth: 340
111 | model: map.supportedMapTypes
112 | onCurrentIndexChanged: map.activeMapType = map.supportedMapTypes[currentIndex]
113 | }
114 |
115 | Button {
116 | text: qsTr("Re-center") + Translator.dummy
117 | icon.source: "qrc:/icons/location.svg"
118 | onClicked: centerMap()
119 | }
120 | }
121 |
122 | //
123 | // Map
124 | //
125 | Rectangle {
126 | Layout.fillWidth: true
127 | Layout.fillHeight: true
128 | color: Universal.background
129 |
130 | border {
131 | width: 2
132 | color: "#646464"
133 | }
134 |
135 | Map {
136 | id: map
137 | anchors.fill: parent
138 | copyrightsVisible: false
139 | color: Universal.background
140 | anchors.margins: parent.border.width
141 | zoomLevel: (map.minimumZoomLevel + map.maximumZoomLevel) / 2
142 |
143 | MapQuickItem {
144 | sourceItem: Rectangle {
145 | id: dot
146 | width: 20
147 | height: 20
148 | opacity: 0.1
149 | color: "#f00"
150 | border.width: 2
151 | radius: width / 2
152 | border.color: "#fff"
153 |
154 | Connections {
155 | target: CSerialManager
156 | onPacketReceived: {
157 | timer.restart()
158 | dot.opacity = 0.8
159 | }
160 | }
161 |
162 | Behavior on opacity { NumberAnimation { duration: 500 } }
163 |
164 | Timer {
165 | id: timer
166 | repeat: true
167 | interval: 500
168 | Component.onCompleted: start()
169 | onTriggered: dot.opacity = CSerialManager.connected ? 0.25 : 0.1
170 | }
171 | }
172 |
173 | coordinate: gpsWorking ? gpsCoordinates : qroCoordinates
174 | anchorPoint: Qt.point(sourceItem.width / 2,
175 | sourceItem.height/ 2)
176 | }
177 |
178 | plugin: Plugin {
179 | name: "mapboxgl"
180 | }
181 | }
182 | }
183 | }
184 |
185 |
--------------------------------------------------------------------------------
/src/DataParser.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #ifndef DATA_PARSER_H
24 | #define DATA_PARSER_H
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | #include "Constants.h"
35 |
36 | class DataParser : public QObject {
37 | Q_OBJECT
38 | Q_PROPERTY(int teamId
39 | READ teamId
40 | NOTIFY dataParsed)
41 | Q_PROPERTY(int packetCount
42 | READ packetCount
43 | NOTIFY dataParsed)
44 | Q_PROPERTY(quint64 missionTime
45 | READ missionTime
46 | NOTIFY dataParsed)
47 | Q_PROPERTY(double altitude
48 | READ altitude
49 | NOTIFY dataParsed)
50 | Q_PROPERTY(double voltage
51 | READ batteryVoltage
52 | NOTIFY dataParsed)
53 | Q_PROPERTY(double intTemperature
54 | READ intTemperature
55 | NOTIFY dataParsed)
56 | Q_PROPERTY(double extTemperature
57 | READ extTemperature
58 | NOTIFY dataParsed)
59 | Q_PROPERTY(double atmosphericPressure
60 | READ atmosphericPressure
61 | NOTIFY dataParsed)
62 | Q_PROPERTY(QString gpsTime
63 | READ gpsTime
64 | NOTIFY dataParsed)
65 | Q_PROPERTY(double gpsAltitude
66 | READ gpsAltitude
67 | NOTIFY dataParsed)
68 | Q_PROPERTY(double gpsLongitude
69 | READ gpsLongitude
70 | NOTIFY dataParsed)
71 | Q_PROPERTY(double gpsLatitude
72 | READ gpsLatitude
73 | NOTIFY dataParsed)
74 | Q_PROPERTY(int gpsSatelliteCount
75 | READ gpsSatelliteCount
76 | NOTIFY dataParsed)
77 | Q_PROPERTY(QVector3D magnetometer
78 | READ magnetomerData
79 | NOTIFY dataParsed)
80 | Q_PROPERTY(QVector3D accelerometer
81 | READ accelerometerData
82 | NOTIFY dataParsed)
83 | Q_PROPERTY(bool parachuteStatus
84 | READ parachuteStatus
85 | NOTIFY dataParsed)
86 | Q_PROPERTY(double airQuality
87 | READ airQuality
88 | NOTIFY dataParsed)
89 | Q_PROPERTY(double carbonMonoxide
90 | READ carbonMonoxide
91 | NOTIFY dataParsed)
92 | Q_PROPERTY(quint32 checksum
93 | READ checksum
94 | NOTIFY dataParsed)
95 | Q_PROPERTY(bool csvLoggingEnabled
96 | READ csvLoggingEnabled
97 | WRITE enableCsvLogging
98 | NOTIFY csvLoggingEnabledChanged)
99 | Q_PROPERTY(int errorCount
100 | READ errorCount
101 | NOTIFY packetError)
102 | Q_PROPERTY(int resetCount
103 | READ resetCount
104 | NOTIFY satelliteReset)
105 | Q_PROPERTY(int successCount
106 | READ successCount
107 | NOTIFY dataParsed)
108 |
109 | public:
110 | enum DataPosition {
111 | kHeader,
112 | kTeamID,
113 | kPacketCount,
114 | kAltitude,
115 | kAtmPressure,
116 | kBatteryVoltage,
117 | kIntTemperature,
118 | kExtTemperature,
119 | kAirQuality,
120 | kCarbonMonoxide,
121 | kGpsTime,
122 | kGpsLongitudeDeg,
123 | kGpsLongitudeMin,
124 | kGpsLatitudeDeg,
125 | kGpsLatitudeMin,
126 | kGpsAltitude,
127 | kGpsSatelliteCount,
128 | kAccelerometerX,
129 | kAccelerometerY,
130 | kAccelerometerZ,
131 | kMagnetometerX,
132 | kMagnetometerY,
133 | kMagnetometerZ,
134 | kMisionTime,
135 | kParachute,
136 | kChecksumCode
137 | };
138 | Q_ENUM(DataPosition);
139 |
140 | signals:
141 | void dataParsed();
142 | void packetError();
143 | void satelliteReset();
144 | void csvLoggingEnabledChanged();
145 |
146 | public:
147 | DataParser();
148 | ~DataParser();
149 |
150 | int resetCount() const;
151 | int errorCount() const;
152 | int successCount() const;
153 |
154 | int teamId() const;
155 | int packetCount() const;
156 | quint64 missionTime() const;
157 |
158 | double altitude() const;
159 | double airQuality() const;
160 | double carbonMonoxide() const;
161 | double intTemperature() const;
162 | double extTemperature() const;
163 | double batteryVoltage() const;
164 | double atmosphericPressure() const;
165 |
166 | bool parachuteStatus() const;
167 |
168 | QString gpsTime() const;
169 | double gpsAltitude() const;
170 | double gpsLatitude() const;
171 | double gpsLongitude() const;
172 | int gpsSatelliteCount() const;
173 |
174 | QVector3D magnetomerData() const;
175 | QVector3D accelerometerData() const;
176 |
177 | quint32 checksum() const;
178 | bool csvLoggingEnabled() const;
179 |
180 | public slots:
181 | void resetData();
182 | void openCsvFile();
183 | void enableCsvLogging(const bool enabled);
184 |
185 | private slots:
186 | void saveCsvData();
187 | void onPacketError();
188 | void onPacketParsed();
189 | void onSatelliteReset();
190 | void parsePacket(const QByteArray &data);
191 |
192 | private:
193 | QFile m_csvFile;
194 | quint32 m_crc32;
195 | int m_resetCount;
196 | int m_errorCount;
197 | int m_successCount;
198 | QVector m_data;
199 | bool m_csvLoggingEnabled;
200 | };
201 |
202 | #endif
203 |
--------------------------------------------------------------------------------
/assets/qml/UI.qml:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import QtQuick 2.0
24 | import QtQuick.Layouts 1.0
25 | import QtQuick.Controls 2.3
26 | import QtQuick.Controls.Universal 2.0
27 |
28 | import "Modules"
29 |
30 | ColumnLayout {
31 | id: ui
32 | spacing: app.spacing
33 | property alias language: langBt.checked
34 | property alias fullscreen: fullscreenBt.checked
35 |
36 | //
37 | // Toolbar
38 | //
39 | RowLayout {
40 | spacing: 0
41 | Layout.fillWidth: true
42 |
43 | //
44 | // Logo
45 | //
46 | ColumnLayout {
47 | spacing: app.spacing
48 |
49 | Image {
50 | opacity: 0.8
51 | sourceSize.width: 240
52 | source: "qrc:/images/kaansat.svg"
53 | Layout.alignment: Qt.AlignVCenter
54 | }
55 |
56 | Label {
57 | opacity: 0.6
58 | font.pixelSize: 10
59 | text: AppName + " v" + AppVersion
60 | }
61 | }
62 |
63 | //
64 | // Spacer
65 | //
66 | Item {
67 | Layout.fillWidth: true
68 | }
69 |
70 | //
71 | // Serial port selector
72 | //
73 | ComboBox {
74 | id: devices
75 | Layout.preferredWidth: 196
76 | model: CSerialManager.serialDevices
77 | enabled: CSerialManager.serialDevices.length > 1
78 | onCurrentIndexChanged: CSerialManager.startComm(currentIndex)
79 | }
80 |
81 | //
82 | // Spacer
83 | //
84 | Item {
85 | width: app.spacing
86 | }
87 |
88 | //
89 | // Baud rate selector
90 | //
91 | ComboBox {
92 | id: baudRate
93 | currentIndex: 3
94 | enabled: CSerialManager.serialDevices.length > 1
95 | onCurrentIndexChanged: CSerialManager.setBaudRate(model[currentIndex])
96 |
97 | model: [
98 | 1200,
99 | 2400,
100 | 4800,
101 | 9600,
102 | 19200,
103 | 38400,
104 | 57600,
105 | 15200,
106 | ]
107 | }
108 |
109 | //
110 | // Spacer
111 | //
112 | Item {
113 | width: 2 * app.spacing
114 | }
115 |
116 | //
117 | // Language button
118 | //
119 | MouseArea {
120 | width: 32
121 | height: 32
122 |
123 | id: langBt
124 | property bool checked: Translator.language == 1
125 |
126 | onClicked: {
127 | checked = !checked
128 | Translator.setLanguage(checked ? 1 : 0)
129 | }
130 |
131 | Image {
132 | sourceSize.width: 32
133 | anchors.centerIn: parent
134 | source: parent.checked ? "qrc:/icons/mexico.svg" :
135 | "qrc:/icons/united-states.svg"
136 | }
137 | }
138 |
139 | //
140 | // Spacer
141 | //
142 | Item {
143 | width: 2 * app.spacing
144 | }
145 |
146 | //
147 | // CSV table button
148 | //
149 | Button {
150 | background: Item {}
151 |
152 | Rectangle {
153 | width: 32
154 | height: 32
155 | radius: width / 2
156 | anchors.centerIn: parent
157 | color: Qt.rgba(35/255, 209/255, 75/255, 1)
158 |
159 | border.width: 1
160 | border.color: Qt.rgba(0, 0, 0, 0.21)
161 | }
162 |
163 | icon.source: "qrc:/icons/csv.svg"
164 | icon.color: Qt.rgba(0, 0, 0, 0.42)
165 | onClicked: CDataParser.openCsvFile()
166 | }
167 |
168 | //
169 | // Spacer
170 | //
171 | Item {
172 | width: app.spacing
173 | }
174 |
175 | //
176 | // Full screen button
177 | //
178 | Button {
179 | id: fullscreenBt
180 | background: Item {}
181 |
182 | Rectangle {
183 | width: 32
184 | height: 32
185 | radius: width / 2
186 | anchors.centerIn: parent
187 | color: Qt.rgba(229/255, 193/255, 58/255, 1)
188 |
189 | border.width: 1
190 | border.color: Qt.rgba(0, 0, 0, 0.21)
191 | }
192 |
193 | checkable: true
194 | icon.color: Qt.rgba(0, 0, 0, 0.42)
195 | onClicked: checked ? app.showFullScreen() : app.showNormal()
196 | icon.source: checked ? "qrc:/icons/fullscreen-exit.svg" :
197 | "qrc:/icons/fullscreen.svg"
198 | }
199 |
200 | //
201 | // Spacer
202 | //
203 | Item {
204 | width: app.spacing
205 | }
206 |
207 | //
208 | // Close button
209 | //
210 | Button {
211 | background: Item {}
212 |
213 | Rectangle {
214 | width: 32
215 | height: 32
216 | radius: width / 2
217 | anchors.centerIn: parent
218 | color: Qt.rgba(246/255, 82/255, 82/255, 1)
219 |
220 | border.width: 1
221 | border.color: Qt.rgba(0, 0, 0, 0.21)
222 | }
223 |
224 | onClicked: app.close()
225 | icon.source: "qrc:/icons/exit.svg"
226 | icon.color: Qt.rgba(0, 0, 0, 0.42)
227 | }
228 | }
229 |
230 | //
231 | // Dashboard
232 | //
233 | Dashboard {
234 | id: dashboard
235 | Layout.fillWidth: true
236 | Layout.fillHeight: true
237 | }
238 |
239 | //
240 | // Connection status dialog
241 | //
242 | Dialog {
243 | id: dialog
244 |
245 | //
246 | // Only close the dialog when the user
247 | // presses on the 'OK' button
248 | //
249 | modal: true
250 | standardButtons: Dialog.Ok
251 | closePolicy: Dialog.NoAutoClose
252 |
253 | //
254 | // Center dialog on app window
255 | //
256 | x: (parent.width - width) / 2
257 | y: (parent.height - height) / 2
258 |
259 | //
260 | // Set min. width to 320 pixels
261 | //
262 | width: Math.max(implicitWidth, 320)
263 |
264 | //
265 | // Used to select after the user closes
266 | // this dialog (only in the case that we could not
267 | // connect to the serial device)
268 | //
269 | property bool error: false
270 | onAccepted: {
271 | if (error)
272 | devices.currentIndex = 0
273 | }
274 |
275 | //
276 | // Message description
277 | //
278 | Label {
279 | id: description
280 | anchors.fill: parent
281 | verticalAlignment: Qt.AlignTop
282 | horizontalAlignment: Qt.AlignLeft
283 | }
284 |
285 | //
286 | // Show dialog when serial device connection status changes
287 | //
288 | Connections {
289 | target: CSerialManager
290 |
291 | onConnectionError: {
292 | dialog.error = true
293 | dialog.title = qsTr("Warning") + Translator.dummy
294 | description.text = qsTr("Disconnected from \"%1\"").arg(deviceName) + Translator.dummy
295 | dialog.open()
296 | }
297 | }
298 | }
299 | }
300 |
301 |
--------------------------------------------------------------------------------
/assets/images/unaq.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/assets/qml/Components/DataGrid.qml:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | import QtQuick 2.0
24 | import QtQuick.Layouts 1.0
25 | import QtQuick.Controls 2.0
26 |
27 | GridLayout {
28 | id: dataGrid
29 |
30 | columns: 2
31 | rowSpacing: app.spacing * 2
32 | columnSpacing: app.spacing
33 |
34 | //
35 | // Mission status
36 | //
37 | GroupBox {
38 | font.family: app.monoFont
39 | title: "// " + qsTr("Mission Status") + Translator.dummy
40 | Layout.fillWidth: true
41 | Layout.fillHeight: true
42 |
43 | background: Rectangle {
44 | color: "#000"
45 | opacity: 0.75
46 | border.width: 2
47 | anchors.fill: parent
48 | anchors.topMargin: 32
49 | border.color: "#646464"
50 | }
51 |
52 | ColumnLayout {
53 | spacing: app.spacing
54 | anchors.centerIn: parent
55 |
56 | DataLabel {
57 | title: qsTr("Mission Time") + Translator.dummy
58 | dataset: {
59 | function pad(n) {
60 | return (n < 10) ? ("0" + n) : n;
61 | }
62 |
63 | var milliseconds = CDataParser.missionTime
64 | var seconds = (milliseconds / 1000)
65 | var minutes = (seconds / 60) % 60
66 |
67 | seconds = seconds % 60
68 | milliseconds = milliseconds % 1000
69 |
70 | seconds = Math.round(seconds)
71 | minutes = Math.round(minutes)
72 | milliseconds = Math.round(milliseconds)
73 |
74 | return pad(minutes) + ":"
75 | + pad(seconds) + "."
76 | + milliseconds.toString()[0]
77 | }
78 | }
79 |
80 | DataLabel {
81 | title: qsTr("Team ID") + Translator.dummy
82 | dataset: CDataParser.teamId
83 | }
84 |
85 | DataLabel {
86 | title: qsTr("Parachute Status") + Translator.dummy
87 | dataset: (CDataParser.parachuteStatus ? qsTr("Open") : qsTr("Closed")) + Translator.dummy
88 | }
89 |
90 | DataLabel {
91 | title: qsTr("Checksum") + Translator.dummy
92 | dataset: (CDataParser.checksum).toString(16)
93 | }
94 | }
95 | }
96 |
97 | //
98 | // Misc. sensors
99 | //
100 | GroupBox {
101 | font.family: app.monoFont
102 | title: "// " + qsTr("Sensor Readings") + Translator.dummy
103 | Layout.fillWidth: true
104 | Layout.fillHeight: true
105 |
106 | background: Rectangle {
107 | color: "#000"
108 | opacity: 0.75
109 | border.width: 2
110 | anchors.fill: parent
111 | anchors.topMargin: 32
112 | border.color: "#646464"
113 | }
114 |
115 | ColumnLayout {
116 | anchors.centerIn: parent
117 |
118 | DataLabel {
119 | units: "m"
120 | title: qsTr("Altitude") + Translator.dummy
121 | dataset: CDataParser.altitude
122 | }
123 |
124 | DataLabel {
125 | units: "KPa"
126 | title: qsTr("Pressure") + Translator.dummy
127 | dataset: CDataParser.atmosphericPressure / 1000.0
128 | }
129 |
130 | DataLabel {
131 | units: "°C"
132 | title: qsTr("Internal Temperature") + Translator.dummy
133 | dataset: CDataParser.intTemperature
134 | }
135 |
136 | DataLabel {
137 | units: "°C"
138 | title: qsTr("External Temperature") + Translator.dummy
139 | dataset: CDataParser.extTemperature
140 | }
141 |
142 | DataLabel {
143 | units: "%"
144 | title: qsTr("Air Quality") + Translator.dummy
145 | dataset: CDataParser.airQuality
146 | }
147 |
148 | DataLabel {
149 | units: "%"
150 | title: qsTr("Carbon Monoxide") + Translator.dummy
151 | dataset: CDataParser.carbonMonoxide
152 | }
153 | }
154 | }
155 |
156 | //
157 | // Accelerometer
158 | //
159 | GroupBox {
160 | font.family: app.monoFont
161 | title: "// " + qsTr("Accelerometer") + Translator.dummy
162 | Layout.fillWidth: true
163 | Layout.fillHeight: true
164 |
165 | background: Rectangle {
166 | color: "#000"
167 | opacity: 0.75
168 | border.width: 2
169 | anchors.fill: parent
170 | anchors.topMargin: 32
171 | border.color: "#646464"
172 | }
173 |
174 | ColumnLayout {
175 | spacing: app.spacing
176 | anchors.centerIn: parent
177 |
178 | DataLabel {
179 | title: "X"
180 | units: "m/s2"
181 | dataset: CDataParser.accelerometer.x
182 | }
183 |
184 | DataLabel {
185 | title: "Y"
186 | units: "m/s2"
187 | dataset: CDataParser.accelerometer.y
188 | }
189 |
190 | DataLabel {
191 | title: "Z"
192 | units: "m/s2"
193 | dataset: CDataParser.accelerometer.z
194 | }
195 | }
196 | }
197 |
198 | //
199 | // Magnetometer
200 | //
201 | GroupBox {
202 | font.family: app.monoFont
203 | title: "// " + qsTr("Magnetometer") + Translator.dummy
204 | Layout.fillWidth: true
205 | Layout.fillHeight: true
206 |
207 | background: Rectangle {
208 | color: "#000"
209 | opacity: 0.75
210 | border.width: 2
211 | anchors.fill: parent
212 | anchors.topMargin: 32
213 | border.color: "#646464"
214 | }
215 |
216 | ColumnLayout {
217 | spacing: app.spacing
218 | anchors.centerIn: parent
219 |
220 | DataLabel {
221 | title: "X"
222 | units: "μT"
223 | dataset: CDataParser.magnetometer.x
224 | }
225 |
226 | DataLabel {
227 | title: "Y"
228 | units: "μT"
229 | dataset: CDataParser.magnetometer.y
230 | }
231 |
232 | DataLabel {
233 | title: "Z"
234 | units: "μT"
235 | dataset: CDataParser.magnetometer.z
236 | }
237 | }
238 | }
239 |
240 | //
241 | // GPS
242 | //
243 | GroupBox {
244 | font.family: app.monoFont
245 | title: "// " + qsTr("GPS Data") + Translator.dummy
246 | Layout.fillWidth: true
247 | Layout.fillHeight: true
248 |
249 | background: Rectangle {
250 | color: "#000"
251 | opacity: 0.75
252 | border.width: 2
253 | anchors.fill: parent
254 | anchors.topMargin: 32
255 | border.color: "#646464"
256 | }
257 |
258 | ColumnLayout {
259 | spacing: app.spacing
260 | anchors.centerIn: parent
261 |
262 | DataLabel {
263 | units: "m"
264 | title: qsTr("Altitude") + Translator.dummy
265 | dataset: CDataParser.gpsAltitude
266 | }
267 |
268 | DataLabel {
269 | title: qsTr("Latitude") + Translator.dummy
270 | dataset: CDataParser.gpsLatitude
271 | }
272 |
273 | DataLabel {
274 | title: qsTr("Longitude") + Translator.dummy
275 | dataset: CDataParser.gpsLongitude
276 | }
277 |
278 | DataLabel {
279 | title: qsTr("Satellites") + Translator.dummy
280 | dataset: CDataParser.gpsSatelliteCount
281 | }
282 |
283 | DataLabel {
284 | title: qsTr("GPS Time") + Translator.dummy
285 | dataset: CDataParser.gpsTime
286 | }
287 | }
288 | }
289 |
290 | //
291 | // Satellite health & comm. status
292 | //
293 | GroupBox {
294 | font.family: app.monoFont
295 | title: "// " + qsTr("Satellite Health") + Translator.dummy
296 | Layout.fillWidth: true
297 | Layout.fillHeight: true
298 |
299 | background: Rectangle {
300 | color: "#000"
301 | opacity: 0.75
302 | border.width: 2
303 | anchors.fill: parent
304 | anchors.topMargin: 32
305 | border.color: "#646464"
306 | }
307 |
308 | ColumnLayout {
309 | spacing: app.spacing
310 | anchors.centerIn: parent
311 |
312 | DataLabel {
313 | units: "V"
314 | title: qsTr("Voltage") + Translator.dummy
315 | dataset: CDataParser.voltage
316 | }
317 |
318 | DataLabel {
319 | title: qsTr("Resets") + Translator.dummy
320 | dataset: CDataParser.resetCount
321 | }
322 |
323 | DataLabel {
324 | title: qsTr("Packet Errors") + Translator.dummy
325 | dataset: CDataParser.errorCount
326 | }
327 |
328 | DataLabel {
329 | title: qsTr("Packets Parsed") + Translator.dummy
330 | dataset: CDataParser.successCount
331 | }
332 | }
333 | }
334 | }
335 |
336 |
--------------------------------------------------------------------------------
/src/SerialManager.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Kaan-Sat
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | #include
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 | #include "Constants.h"
34 | #include "SerialManager.h"
35 |
36 | /**
37 | * @brief Pointer to the only instance of this class.
38 | *
39 | * We need to use a single-instance approach so that all application modules
40 | * and classes can communicate and use the current serial device without dealing
41 | * with permission and/or race issues.
42 | */
43 | static SerialManager* instance = Q_NULLPTR;
44 |
45 | /**
46 | * @brief Constructor for the @a SerialManager class
47 | */
48 | SerialManager::SerialManager() :
49 | m_baudRate(9600),
50 | m_dataLen(-1),
51 | m_port(Q_NULLPTR),
52 | m_enableFileLogging(false)
53 | {
54 | connect(this, &SerialManager::packetReceived,
55 | this, &SerialManager::formatReceivedPacket);
56 | connect(this, &SerialManager::connectionChanged,
57 | this, &SerialManager::configureLogFile);
58 |
59 | QTimer::singleShot(500, this, &SerialManager::refreshSerialDevices);
60 | }
61 |
62 | /**
63 | * @brief Closes the comm. channels with the current device and closes
64 | * the current log file
65 | */
66 | SerialManager::~SerialManager() {
67 | if (m_port != Q_NULLPTR)
68 | m_port->close();
69 |
70 | if (m_packetLog.isOpen())
71 | m_packetLog.close();
72 | }
73 |
74 | /**
75 | * @returns The only instance of the @c SerialManager class, we need
76 | * to have only one instance for every application module to
77 | * interface with the same serial device without getting into
78 | * permission issues or using additional resources
79 | */
80 | SerialManager* SerialManager::getInstance() {
81 | if (instance == Q_NULLPTR)
82 | instance = new SerialManager();
83 |
84 | return instance;
85 | }
86 |
87 | /**
88 | * @returns the baud rate used to communicate with the serial device
89 | */
90 | int SerialManager::baudRate() const {
91 | return m_baudRate;
92 | }
93 |
94 | /**
95 | * @returns @c true if the application is connected to any serial
96 | * device, otherwise, this function shall return @c false
97 | */
98 | bool SerialManager::connected() const {
99 | if (m_port != Q_NULLPTR)
100 | return m_port->isOpen();
101 |
102 | return false;
103 | }
104 |
105 | /**
106 | * @returns @c true if the class will save all inconming data in a nice HTML
107 | * formatted file with received data and timestamps
108 | */
109 | bool SerialManager::fileLoggingEnabled() const {
110 | return m_enableFileLogging;
111 | }
112 |
113 | /**
114 | * @brief SerialManager::deviceName
115 | * @return
116 | */
117 | QString SerialManager::deviceName() const {
118 | if (m_port)
119 | return m_port->portName();
120 |
121 | return "Undefined";
122 | }
123 |
124 | /**
125 | * @returns An user-friendly string that represents the number of bytes
126 | * received from the current serial device.
127 | */
128 | QString SerialManager::receivedBytes() const {
129 | if (m_port != Q_NULLPTR && m_dataLen >= 0)
130 | return sizeStr(m_dataLen);
131 |
132 | return "0 " + tr("bytes");
133 | }
134 |
135 | /**
136 | * @returns A list with the port names (such as COM1, COM2, ttyACMO) of the
137 | * ports that have any serial device connected to them
138 | */
139 | QStringList SerialManager::serialDevices() const {
140 | return m_serialDevices;
141 | }
142 |
143 | void SerialManager::openLogFile() {
144 | if (packetLogAvailable())
145 | QDesktopServices::openUrl(QUrl::fromLocalFile(m_packetLog.fileName()));
146 | }
147 |
148 | /**
149 | * Changes the baud @a rate used to communicate with the serial device
150 | */
151 | void SerialManager::setBaudRate(const int rate) {
152 | if (rate > 0) {
153 | m_baudRate = rate;
154 |
155 | if (m_port)
156 | m_port->setBaudRate(baudRate());
157 |
158 | emit baudRateChanged();
159 | }
160 | }
161 |
162 | /**
163 | * @brief SerialManager::startComm
164 | * @param device
165 | */
166 | void SerialManager::startComm(const int device) {
167 | // Disconnect current serial port device
168 | disconnectDevice();
169 |
170 | // Ignore the