px4-configuration 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. px4_configuration-0.1.0/.gitignore +4 -0
  2. px4_configuration-0.1.0/PKG-INFO +252 -0
  3. px4_configuration-0.1.0/README.md +237 -0
  4. px4_configuration-0.1.0/configs/default-rc.params +15 -0
  5. px4_configuration-0.1.0/configs/generic-quad-airframe.params +4 -0
  6. px4_configuration-0.1.0/configs/mrs-generic.params +12 -0
  7. px4_configuration-0.1.0/configs/platforms/x500.params +12 -0
  8. px4_configuration-0.1.0/configs/sd-card/extras.txt +13 -0
  9. px4_configuration-0.1.0/px4_configuration/__init__.py +15 -0
  10. px4_configuration-0.1.0/px4_configuration/api/__init__.py +11 -0
  11. px4_configuration-0.1.0/px4_configuration/api/config.py +22 -0
  12. px4_configuration-0.1.0/px4_configuration/api/main.py +262 -0
  13. px4_configuration-0.1.0/px4_configuration/api/models.py +120 -0
  14. px4_configuration-0.1.0/px4_configuration/api/services/__init__.py +9 -0
  15. px4_configuration-0.1.0/px4_configuration/api/services/calibration_service.py +136 -0
  16. px4_configuration-0.1.0/px4_configuration/api/services/health_service.py +131 -0
  17. px4_configuration-0.1.0/px4_configuration/api/services/param_service.py +150 -0
  18. px4_configuration-0.1.0/px4_configuration/api/services/sdcard_service.py +89 -0
  19. px4_configuration-0.1.0/px4_configuration/api/services/shell_service.py +65 -0
  20. px4_configuration-0.1.0/px4_configuration/api/utils/__init__.py +1 -0
  21. px4_configuration-0.1.0/px4_configuration/api/utils/calibration_parser.py +248 -0
  22. px4_configuration-0.1.0/pyproject.toml +38 -0
  23. px4_configuration-0.1.0/requirements.txt +6 -0
  24. px4_configuration-0.1.0/scripts/calibrate.py +74 -0
  25. px4_configuration-0.1.0/scripts/px_uploader.py +926 -0
  26. px4_configuration-0.1.0/scripts/set-params.py +73 -0
  27. px4_configuration-0.1.0/scripts/shell.py +58 -0
  28. px4_configuration-0.1.0/scripts/upload-sdcard-config.py +34 -0
@@ -0,0 +1,4 @@
1
+ .venv
2
+ .vscode
3
+ __pycache__/
4
+ dist/
@@ -0,0 +1,252 @@
1
+ Metadata-Version: 2.4
2
+ Name: px4-configuration
3
+ Version: 0.1.0
4
+ Summary: Tools and REST API for configuring PX4 from a companion computer
5
+ Author-email: Alex <bonnefond@fly4future.com>
6
+ License: BSD-3-Clause
7
+ Requires-Python: >=3.8
8
+ Requires-Dist: fastapi>=0.104.0
9
+ Requires-Dist: mavsdk==3.0.1
10
+ Requires-Dist: python-multipart>=0.0.6
11
+ Requires-Dist: sse-starlette>=1.6.5
12
+ Requires-Dist: tqdm==4.67.1
13
+ Requires-Dist: uvicorn[standard]>=0.24.0
14
+ Description-Content-Type: text/markdown
15
+
16
+ # px4-configuration
17
+
18
+ Repository that collects scripts to configure and modify PX4 from a companion Linux computer. All tooling is built on top of [MAVSDK-Python](https://github.com/mavlink/MAVSDK-Python).
19
+
20
+ ## Installation
21
+
22
+ ### Development Installation
23
+
24
+ ```bash
25
+ # Optional: create a virtual environment
26
+ python3 -m venv .venv
27
+ source .venv/bin/activate
28
+
29
+ # Install the package (installs all required dependencies)
30
+ pip install -e .
31
+ ```
32
+
33
+ ### Building a Wheel Package
34
+
35
+ To build a distributable wheel (`.whl`) file:
36
+
37
+ ```bash
38
+ # Install build tools (if not already installed)
39
+ pip install build
40
+
41
+ # Build the wheel package
42
+ python -m build --wheel
43
+
44
+ # The wheel file will be created in the dist/ directory
45
+ # Example: dist/px4_configuration-0.1.0-py3-none-any.whl
46
+ ```
47
+
48
+ To build both wheel and source distribution:
49
+
50
+ ```bash
51
+ python -m build
52
+ ```
53
+
54
+ **Installing from a built wheel:**
55
+
56
+ ```bash
57
+ # Install from the wheel file
58
+ pip install dist/px4_configuration-0.1.0-py3-none-any.whl
59
+ ```
60
+
61
+ ## Requirements
62
+
63
+ - Python 3.8+
64
+ - PX4 flight controller connected over serial (e.g. `/dev/pixhawk`)
65
+ - User added to the `dialout` group for serial access (`sudo usermod -aG dialout $USER`)
66
+
67
+ ## Scripts
68
+
69
+ _All scripts use a serial connection to talk to PX4._
70
+
71
+ - `scripts/calibrate.py` – run gyro, accel, mag, level and (future) ESC calibration
72
+ - `scripts/set-params.py` – bulk upload parameters from `.params` files in `configs/`
73
+ - `scripts/upload-sdcard-config.py` – upload files (e.g. `extras.txt`) to the PX4 SD card via MAVLink FTP
74
+ - `scripts/shell.py` – open an interactive PX4 NSH shell session over MAVLink
75
+ - `scripts/px_uploader.py` – PX4 firmware uploader (original PX4 script, unverified here)
76
+
77
+ ## REST API (FastAPI)
78
+
79
+ The companion computer can expose the same functionality through a REST API located in `px4_configuration/api/`.
80
+
81
+ ### Run the API server
82
+
83
+ ```bash
84
+ # Using the packaged console script
85
+ px4-config-api --host 0.0.0.0 --port 8000
86
+
87
+ # Or via the helper module
88
+ python run_api.py
89
+
90
+ # Or directly with uvicorn
91
+ uvicorn px4_configuration.api.main:app --host 0.0.0.0 --port 8000
92
+ ```
93
+
94
+ ### Endpoints
95
+
96
+ - `GET /api/health` – health check
97
+ - `POST /api/calibration/start` – start selected calibrations, returns Server-Sent Events (SSE) with progress
98
+ - `POST /api/params/upload` – upload a `.params` file (multipart form), SSE progress stream
99
+ - `POST /api/sdcard/upload` – upload a file (e.g. `extras.txt`) to the SD card, SSE progress stream
100
+ - `WS /api/shell/connect` – interactive PX4 shell over WebSocket
101
+
102
+ All endpoints accept optional `port` and `baudrate` (defaults `/dev/pixhawk`, `2000000`). SSE responses emit JSON payloads with keys such as `type`, `message`, `progress`, etc.
103
+
104
+ ### Calibration Message Structure
105
+
106
+ The `/api/calibration/start` endpoint returns structured JSON messages via Server-Sent Events (SSE). Each calibration type has a specific message format:
107
+
108
+ #### Accelerometer Calibration
109
+
110
+ ```json
111
+ {
112
+ "type": "accelerometer_progress",
113
+ "progress": 0.17,
114
+ "status_text": "down side result: [0.020 0.819 -9.750]",
115
+ "pending_orientations": ["back", "front", "left", "right", "up"],
116
+ "current_orientation": "down",
117
+ "current_message": "measuring",
118
+ "result": [0.020, 0.819, -9.750],
119
+ "is_complete": false
120
+ }
121
+ ```
122
+
123
+ **Fields:**
124
+ - `pending_orientations`: List of remaining orientations to measure (e.g., `["back", "front", "left", "right", "up"]`)
125
+ - `current_orientation`: Currently detected orientation being measured (e.g., `"down"`, `"left"`)
126
+ - `current_message`: Instruction type - `"hold_still"`, `"rest_detected"`, `"measuring"`, `"rotate"`, `"orientation_detected"`, `"already_completed"`, `"complete"`
127
+ - `progress`: Progress value (0.0 to 1.0)
128
+ - `result`: Measurement result array `[x, y, z]` when available
129
+ - `is_complete`: Boolean indicating completion
130
+
131
+ **Completion message:**
132
+ ```json
133
+ {
134
+ "type": "accelerometer_complete",
135
+ "message": "Accelerometer calibration finished",
136
+ "is_complete": true
137
+ }
138
+ ```
139
+
140
+ #### Magnetometer Calibration
141
+
142
+ ```json
143
+ {
144
+ "type": "magnetometer_progress",
145
+ "progress": 0.33,
146
+ "status_text": "right orientation detected",
147
+ "pending_orientations": ["back", "front", "left", "up"],
148
+ "current_orientation": "right",
149
+ "current_message": "orientation_detected",
150
+ "is_complete": false
151
+ }
152
+ ```
153
+
154
+ **Fields:**
155
+ - `pending_orientations`: List of remaining orientations to measure
156
+ - `current_orientation`: Currently detected orientation
157
+ - `current_message`: Instruction type - `"rotate"`, `"hold_still"`, `"rest_detected"`, `"motion_detected"`, `"orientation_detected"`, `"already_completed"`, `"complete"`
158
+ - `progress`: Progress value (0.0 to 1.0) that increments during rotation
159
+ - `is_complete`: Boolean indicating completion (true when progress >= 1.0)
160
+
161
+ **Completion message:**
162
+ ```json
163
+ {
164
+ "type": "magnetometer_complete",
165
+ "message": "Magnetometer calibration finished",
166
+ "is_complete": true
167
+ }
168
+ ```
169
+
170
+ #### Gyroscope Calibration
171
+
172
+ ```json
173
+ {
174
+ "type": "gyroscope_progress",
175
+ "progress": 0.5,
176
+ "status_text": null,
177
+ "current_message": "calibrating",
178
+ "is_complete": false
179
+ }
180
+ ```
181
+
182
+ **Fields:**
183
+ - `progress`: Progress value (0.0 to 1.0)
184
+ - `current_message`: `"calibrating"` during progress, `"complete"` when done
185
+ - `is_complete`: Boolean indicating completion (true when progress >= 1.0)
186
+
187
+ **Completion message:**
188
+ ```json
189
+ {
190
+ "type": "gyroscope_complete",
191
+ "message": "Gyroscope calibration finished",
192
+ "is_complete": true
193
+ }
194
+ ```
195
+
196
+ #### Level Horizon Calibration
197
+
198
+ ```json
199
+ {
200
+ "type": "horizon_progress",
201
+ "progress": 0.4,
202
+ "status_text": null,
203
+ "current_message": "calibrating",
204
+ "is_complete": false
205
+ }
206
+ ```
207
+
208
+ **Fields:**
209
+ - `progress`: Progress value (0.0 to 1.0)
210
+ - `current_message`: `"calibrating"` during progress, `"complete"` when done
211
+ - `is_complete`: Boolean indicating completion (true when progress >= 1.0)
212
+
213
+ **Completion message:**
214
+ ```json
215
+ {
216
+ "type": "horizon_complete",
217
+ "message": "Level horizon calibration finished",
218
+ "is_complete": true
219
+ }
220
+ ```
221
+
222
+ #### Status Messages
223
+
224
+ General status messages are also emitted:
225
+ ```json
226
+ {
227
+ "type": "status",
228
+ "message": "Starting accelerometer calibration..."
229
+ }
230
+ ```
231
+
232
+ ```json
233
+ {
234
+ "type": "error",
235
+ "message": "Calibration failed: <error details>"
236
+ }
237
+ ```
238
+
239
+ ```json
240
+ {
241
+ "type": "success",
242
+ "message": "All calibrations completed"
243
+ }
244
+ ```
245
+
246
+ ## Notes
247
+
248
+ - Ensure the vehicle is disarmed and stationary before running calibration or parameter uploads.
249
+ - The API and scripts require serial access; add your user to the `dialout` group if needed.
250
+ - Example parameter files and `extras.txt` live under the `configs/` directory.
251
+
252
+
@@ -0,0 +1,237 @@
1
+ # px4-configuration
2
+
3
+ Repository that collects scripts to configure and modify PX4 from a companion Linux computer. All tooling is built on top of [MAVSDK-Python](https://github.com/mavlink/MAVSDK-Python).
4
+
5
+ ## Installation
6
+
7
+ ### Development Installation
8
+
9
+ ```bash
10
+ # Optional: create a virtual environment
11
+ python3 -m venv .venv
12
+ source .venv/bin/activate
13
+
14
+ # Install the package (installs all required dependencies)
15
+ pip install -e .
16
+ ```
17
+
18
+ ### Building a Wheel Package
19
+
20
+ To build a distributable wheel (`.whl`) file:
21
+
22
+ ```bash
23
+ # Install build tools (if not already installed)
24
+ pip install build
25
+
26
+ # Build the wheel package
27
+ python -m build --wheel
28
+
29
+ # The wheel file will be created in the dist/ directory
30
+ # Example: dist/px4_configuration-0.1.0-py3-none-any.whl
31
+ ```
32
+
33
+ To build both wheel and source distribution:
34
+
35
+ ```bash
36
+ python -m build
37
+ ```
38
+
39
+ **Installing from a built wheel:**
40
+
41
+ ```bash
42
+ # Install from the wheel file
43
+ pip install dist/px4_configuration-0.1.0-py3-none-any.whl
44
+ ```
45
+
46
+ ## Requirements
47
+
48
+ - Python 3.8+
49
+ - PX4 flight controller connected over serial (e.g. `/dev/pixhawk`)
50
+ - User added to the `dialout` group for serial access (`sudo usermod -aG dialout $USER`)
51
+
52
+ ## Scripts
53
+
54
+ _All scripts use a serial connection to talk to PX4._
55
+
56
+ - `scripts/calibrate.py` – run gyro, accel, mag, level and (future) ESC calibration
57
+ - `scripts/set-params.py` – bulk upload parameters from `.params` files in `configs/`
58
+ - `scripts/upload-sdcard-config.py` – upload files (e.g. `extras.txt`) to the PX4 SD card via MAVLink FTP
59
+ - `scripts/shell.py` – open an interactive PX4 NSH shell session over MAVLink
60
+ - `scripts/px_uploader.py` – PX4 firmware uploader (original PX4 script, unverified here)
61
+
62
+ ## REST API (FastAPI)
63
+
64
+ The companion computer can expose the same functionality through a REST API located in `px4_configuration/api/`.
65
+
66
+ ### Run the API server
67
+
68
+ ```bash
69
+ # Using the packaged console script
70
+ px4-config-api --host 0.0.0.0 --port 8000
71
+
72
+ # Or via the helper module
73
+ python run_api.py
74
+
75
+ # Or directly with uvicorn
76
+ uvicorn px4_configuration.api.main:app --host 0.0.0.0 --port 8000
77
+ ```
78
+
79
+ ### Endpoints
80
+
81
+ - `GET /api/health` – health check
82
+ - `POST /api/calibration/start` – start selected calibrations, returns Server-Sent Events (SSE) with progress
83
+ - `POST /api/params/upload` – upload a `.params` file (multipart form), SSE progress stream
84
+ - `POST /api/sdcard/upload` – upload a file (e.g. `extras.txt`) to the SD card, SSE progress stream
85
+ - `WS /api/shell/connect` – interactive PX4 shell over WebSocket
86
+
87
+ All endpoints accept optional `port` and `baudrate` (defaults `/dev/pixhawk`, `2000000`). SSE responses emit JSON payloads with keys such as `type`, `message`, `progress`, etc.
88
+
89
+ ### Calibration Message Structure
90
+
91
+ The `/api/calibration/start` endpoint returns structured JSON messages via Server-Sent Events (SSE). Each calibration type has a specific message format:
92
+
93
+ #### Accelerometer Calibration
94
+
95
+ ```json
96
+ {
97
+ "type": "accelerometer_progress",
98
+ "progress": 0.17,
99
+ "status_text": "down side result: [0.020 0.819 -9.750]",
100
+ "pending_orientations": ["back", "front", "left", "right", "up"],
101
+ "current_orientation": "down",
102
+ "current_message": "measuring",
103
+ "result": [0.020, 0.819, -9.750],
104
+ "is_complete": false
105
+ }
106
+ ```
107
+
108
+ **Fields:**
109
+ - `pending_orientations`: List of remaining orientations to measure (e.g., `["back", "front", "left", "right", "up"]`)
110
+ - `current_orientation`: Currently detected orientation being measured (e.g., `"down"`, `"left"`)
111
+ - `current_message`: Instruction type - `"hold_still"`, `"rest_detected"`, `"measuring"`, `"rotate"`, `"orientation_detected"`, `"already_completed"`, `"complete"`
112
+ - `progress`: Progress value (0.0 to 1.0)
113
+ - `result`: Measurement result array `[x, y, z]` when available
114
+ - `is_complete`: Boolean indicating completion
115
+
116
+ **Completion message:**
117
+ ```json
118
+ {
119
+ "type": "accelerometer_complete",
120
+ "message": "Accelerometer calibration finished",
121
+ "is_complete": true
122
+ }
123
+ ```
124
+
125
+ #### Magnetometer Calibration
126
+
127
+ ```json
128
+ {
129
+ "type": "magnetometer_progress",
130
+ "progress": 0.33,
131
+ "status_text": "right orientation detected",
132
+ "pending_orientations": ["back", "front", "left", "up"],
133
+ "current_orientation": "right",
134
+ "current_message": "orientation_detected",
135
+ "is_complete": false
136
+ }
137
+ ```
138
+
139
+ **Fields:**
140
+ - `pending_orientations`: List of remaining orientations to measure
141
+ - `current_orientation`: Currently detected orientation
142
+ - `current_message`: Instruction type - `"rotate"`, `"hold_still"`, `"rest_detected"`, `"motion_detected"`, `"orientation_detected"`, `"already_completed"`, `"complete"`
143
+ - `progress`: Progress value (0.0 to 1.0) that increments during rotation
144
+ - `is_complete`: Boolean indicating completion (true when progress >= 1.0)
145
+
146
+ **Completion message:**
147
+ ```json
148
+ {
149
+ "type": "magnetometer_complete",
150
+ "message": "Magnetometer calibration finished",
151
+ "is_complete": true
152
+ }
153
+ ```
154
+
155
+ #### Gyroscope Calibration
156
+
157
+ ```json
158
+ {
159
+ "type": "gyroscope_progress",
160
+ "progress": 0.5,
161
+ "status_text": null,
162
+ "current_message": "calibrating",
163
+ "is_complete": false
164
+ }
165
+ ```
166
+
167
+ **Fields:**
168
+ - `progress`: Progress value (0.0 to 1.0)
169
+ - `current_message`: `"calibrating"` during progress, `"complete"` when done
170
+ - `is_complete`: Boolean indicating completion (true when progress >= 1.0)
171
+
172
+ **Completion message:**
173
+ ```json
174
+ {
175
+ "type": "gyroscope_complete",
176
+ "message": "Gyroscope calibration finished",
177
+ "is_complete": true
178
+ }
179
+ ```
180
+
181
+ #### Level Horizon Calibration
182
+
183
+ ```json
184
+ {
185
+ "type": "horizon_progress",
186
+ "progress": 0.4,
187
+ "status_text": null,
188
+ "current_message": "calibrating",
189
+ "is_complete": false
190
+ }
191
+ ```
192
+
193
+ **Fields:**
194
+ - `progress`: Progress value (0.0 to 1.0)
195
+ - `current_message`: `"calibrating"` during progress, `"complete"` when done
196
+ - `is_complete`: Boolean indicating completion (true when progress >= 1.0)
197
+
198
+ **Completion message:**
199
+ ```json
200
+ {
201
+ "type": "horizon_complete",
202
+ "message": "Level horizon calibration finished",
203
+ "is_complete": true
204
+ }
205
+ ```
206
+
207
+ #### Status Messages
208
+
209
+ General status messages are also emitted:
210
+ ```json
211
+ {
212
+ "type": "status",
213
+ "message": "Starting accelerometer calibration..."
214
+ }
215
+ ```
216
+
217
+ ```json
218
+ {
219
+ "type": "error",
220
+ "message": "Calibration failed: <error details>"
221
+ }
222
+ ```
223
+
224
+ ```json
225
+ {
226
+ "type": "success",
227
+ "message": "All calibrations completed"
228
+ }
229
+ ```
230
+
231
+ ## Notes
232
+
233
+ - Ensure the vehicle is disarmed and stationary before running calibration or parameter uploads.
234
+ - The API and scripts require serial access; add your user to the `dialout` group if needed.
235
+ - Example parameter files and `extras.txt` live under the `configs/` directory.
236
+
237
+
@@ -0,0 +1,15 @@
1
+ #RC channels mapping (ATER)
2
+ RC_MAP_ROLL, 1
3
+ RC_MAP_THROTTLE, 2
4
+ RC_MAP_PITCH, 3
5
+ RC_MAP_YAW, 4
6
+ #Switches
7
+ RC_MAP_OFFB_SW, 5
8
+ RC_MAP_FLTMODE, 6
9
+ # MANUAL - ALTITUDE - POSITION
10
+ COM_FLTMODE1, 0
11
+ COM_FLTMODE2, -1
12
+ COM_FLTMODE3, -1
13
+ COM_FLTMODE4, 1
14
+ COM_FLTMODE5, -1
15
+ COM_FLTMODE6, 2
@@ -0,0 +1,4 @@
1
+ #generic-quadrotor-airframe
2
+ SYS_AUTOSTART, 4001
3
+ #reset params to airframe defaults
4
+ SYS_AUTOCONFIG, 1
@@ -0,0 +1,12 @@
1
+ #RC-loss-related
2
+ RC_MAP_FAILSAFE, 2
3
+ RC_FAILS_THR, 950
4
+ #rc-loss failsafe - land mode
5
+ NAV_RCL_ACT, 3
6
+ #motors
7
+ PWM_MAIN_FUNC1, 101
8
+ PWM_MAIN_FUNC2, 102
9
+ PWM_MAIN_FUNC3, 103
10
+ PWM_MAIN_FUNC4, 104
11
+ #garmin
12
+ SENS_EN_LL40LS, 2
@@ -0,0 +1,12 @@
1
+ #Battery settings
2
+ BAT1_N_CELLS, 4
3
+ BAT1_V_CHARGED, 4.2
4
+ #Vehicle dimensions [m]
5
+ CA_ROTOR0_PX, 0.25
6
+ CA_ROTOR0_PY, 0.25
7
+ CA_ROTOR1_PX, -0.25
8
+ CA_ROTOR1_PY, -0.25
9
+ CA_ROTOR2_PX, 0.25
10
+ CA_ROTOR2_PY, -0.25
11
+ CA_ROTOR3_PX, -0.25
12
+ CA_ROTOR3_PY, 0.25
@@ -0,0 +1,13 @@
1
+ mavlink start -d /dev/ttyS1 -b 2000000
2
+ mavlink stream -d /dev/ttyS1 -s ATTITUDE -r 100
3
+ mavlink stream -d /dev/ttyS1 -s ATTITUDE_TARGET -r 100
4
+ mavlink stream -d /dev/ttyS1 -s HIGHRES_IMU -r 100
5
+ mavlink stream -d /dev/ttyS1 -s RC_CHANNELS -r 10
6
+ mavlink stream -d /dev/ttyS1 -s LOCAL_POSITION_NED -r 100
7
+ mavlink stream -d /dev/ttyS1 -s ODOMETRY -r 100
8
+ mavlink stream -d /dev/ttyS1 -s GLOBAL_POSITION_INT -r 100
9
+ mavlink stream -d /dev/ttyS1 -s SYS_STATUS -r 10
10
+ mavlink stream -d /dev/ttyS1 -s DISTANCE_SENSOR -r 100
11
+ mavlink stream -d /dev/ttyS1 -s HEARTBEAT -r 100
12
+ mavlink stream -d /dev/ttyS1 -s UTM_GLOBAL_POSITION -r 1
13
+ usleep 100000
@@ -0,0 +1,15 @@
1
+ """PX4 Configuration package."""
2
+
3
+ __all__ = ["api"]
4
+
5
+
6
+ def __getattr__(name):
7
+ if name == "__version__":
8
+ from importlib.metadata import version, PackageNotFoundError
9
+
10
+ try:
11
+ return version("px4-configuration")
12
+ except PackageNotFoundError:
13
+ return "0.0.0"
14
+ raise AttributeError(name)
15
+
@@ -0,0 +1,11 @@
1
+ """PX4 Configuration REST API package."""
2
+
3
+ __all__ = [
4
+ "config",
5
+ "models",
6
+ "services",
7
+ "main",
8
+ ]
9
+
10
+ __version__ = "1.0.0"
11
+
@@ -0,0 +1,22 @@
1
+ """Configuration settings for the PX4 Configuration API."""
2
+
3
+ import os
4
+
5
+
6
+ class Settings:
7
+ """Application settings with defaults."""
8
+
9
+ # Default serial connection settings
10
+ default_port: str = os.getenv("PX4_DEFAULT_PORT", "/dev/pixhawk")
11
+ default_baudrate: int = int(os.getenv("PX4_DEFAULT_BAUDRATE", "2000000"))
12
+
13
+ # API settings
14
+ api_title: str = "PX4 Configuration API"
15
+ api_version: str = "1.0.0"
16
+ api_description: str = (
17
+ "REST API for configuring PX4 flight controller from companion computer"
18
+ )
19
+
20
+
21
+ settings = Settings()
22
+