Skip to content

Commit 38e5aea

Browse files
committed
feat: major refactor, performance improvements, reduction in code.
1 parent fe8960c commit 38e5aea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+5044
-3193
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,8 @@
4444
*.claude
4545
CLAUDE.md
4646
AGENTS.md
47+
CLONE_OPTIMIZATION_*
48+
CONFIG_MIGRATION_*
49+
PHASE_*
50+
VALIDATION_CHECKLIST*
51+
COPYRIGHT_HEADERS.md

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2025 Jesse Hernandez
3+
Copyright (c) 2025 Jesse Hernandez, Digital Hand LLC
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

LICENSES/BSD-2-Clause.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
BSD 2-Clause License
2+
3+
Copyright (c) <year>, <copyright holder>
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

LICENSES/GPL-2.0-only.txt

Lines changed: 338 additions & 0 deletions
Large diffs are not rendered by default.

LICENSE_POLICY.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# License Policy
2+
3+
This repository currently contains a mix of source provenance and licenses.
4+
5+
## Source-Of-Truth Rules
6+
7+
1. The effective license for a file is the file-level SPDX header.
8+
2. If a file has no SPDX header, treat that as a compliance gap and add one.
9+
3. Existing third-party notices must be preserved.
10+
11+
## License Documents
12+
13+
- MIT license: `LICENSE`
14+
- GPL-2.0-only text: `LICENSES/GPL-2.0-only.txt`
15+
- BSD-2-Clause text: `LICENSES/BSD-2-Clause.txt`
16+
- Repository notice: `NOTICE`
17+
18+
## New Code Policy (Digital Hand)
19+
20+
For brand-new files authored in this repository:
21+
22+
- Use `SPDX-License-Identifier: MIT`.
23+
- Use Digital Hand copyright notice.
24+
- Header template:
25+
26+
```cpp
27+
/* SPDX-License-Identifier: MIT */
28+
/*
29+
* Copyright (c) 2026, Digital Hand LLC.
30+
*/
31+
```
32+
33+
## Derived / Upstream-Origin Code Policy
34+
35+
For files derived from upstream/original PiTrac code:
36+
37+
- Keep existing upstream SPDX and copyright notices.
38+
- Add Digital Hand copyright lines for substantial new contributions.
39+
- Do not remove upstream notices without explicit legal approval.
40+
41+
Example:
42+
43+
```cpp
44+
/* SPDX-License-Identifier: GPL-2.0-only */
45+
/*
46+
* Copyright (C) 2022-2025, Verdant Consultants, LLC.
47+
* Copyright (c) 2026, Digital Hand LLC.
48+
*/
49+
```
50+
51+
## Third-Party Imported Code
52+
53+
- Keep original SPDX/license headers exactly as provided.
54+
- Do not replace with MIT headers.
55+
- Keep required attribution/license files in-tree.
56+
57+
## Practical Workflow
58+
59+
1. Determine whether the file is brand-new or derived.
60+
2. Apply the matching header template.
61+
3. Keep SPDX and copyright line ordering consistent.
62+
4. Run a quick audit before release:
63+
64+
```bash
65+
rg -n "SPDX-License-Identifier|Copyright" -S src pitrac-cli
66+
```
67+
68+
## Notes
69+
70+
- Refactor percentage does not automatically relicense inherited code.
71+
- Fork status also does not change notice obligations.

NOTICE

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
This repository contains a mix of code under different licenses.
2+
3+
License resolution order:
4+
1. File-level SPDX header is authoritative for that file.
5+
2. If a file has no SPDX header, treat that as a compliance gap.
6+
7+
Primary license documents in this repository:
8+
- MIT: LICENSE
9+
- GPL-2.0-only: LICENSES/GPL-2.0-only.txt
10+
- BSD-2-Clause: LICENSES/BSD-2-Clause.txt
11+
12+
Attribution and provenance:
13+
- Upstream/third-party notices are preserved in their source files.
14+
- Net-new Digital Hand authored code should use MIT + Digital Hand header.
15+
- See LICENSE_POLICY.md and COPYRIGHT_HEADERS.md for contributor rules.

README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,16 @@ Same C++ code base as https://github.com/PiTracLM/PiTrac. However, this project
2929
- [Known Issues](#known-issues)
3030
- [System Sequence Diagram](#system-sequence-diagram)
3131
- [Architecture Diagrams](#architecture-diagrams)
32+
- [Runtime Architecture](#runtime-architecture)
33+
- [Data Flow Overview](#data-flow-overview)
34+
- [Ball Hit Flow](#ball-hit-flow)
35+
- [Hardware Topology](#hardware-topology)
36+
- [Module Dependencies](#module-dependencies)
37+
- [Calibration Flows](#calibration-flows)
3238
- [Simulator Data](#simulator-data)
39+
- [Licensing](#licensing)
40+
- [License Files](#license-files)
41+
- [File-Level SPDX Rules](#file-level-spdx-rules)
3342
- [Additional Resources](#additional-resources)
3443

3544
## What this is not
@@ -420,3 +429,81 @@ See [`.github/workflows/ci.yml`](.github/workflows/ci.yml) for CI configuration.
420429
## Known Issues
421430

422431
- **ONNX Runtime Eigen hash mismatch** – The upstream `onnxruntime-1.17.3` source bundles Eigen via `cmake/external/eigen.cmake`, but the published hash no longer matches the live tarball. When the `pitrac-cli install` command or a manual build run `cmake`, the fetch step fails with a message similar to `HASH mismatch for file: eigen-...`. To work around this, edit `~/src/onnxruntime-1.17.3/cmake/external/eigen.cmake` (or wherever you unpacked the sources) and update the `URL_HASH` line to `SHA1=32b145f525a8308d7ab1c09388b2e288312d8eba`, then re-run the build. Track the upstream ONNX Runtime issue for a permanent fix.
432+
433+
## System Sequence Diagram
434+
435+
High-level lifecycle from startup through shot processing:
436+
437+
![PiTrac system sequence](assets/images/basic_ssd.png)
438+
439+
## Architecture Diagrams
440+
441+
### Runtime Architecture
442+
443+
Current refactored runtime view:
444+
445+
![PiTrac runtime architecture](assets/images/architecture-overview.png)
446+
447+
### Data Flow Overview
448+
449+
Configuration, runtime IPC, simulator send path, and artifact writes:
450+
451+
![PiTrac data flow overview](assets/images/data-flow-overview.png)
452+
453+
### Ball Hit Flow
454+
455+
Camera1 detection to camera2 capture to simulator output:
456+
457+
![PiTrac ball hit flow](assets/images/golf-simulator-ball-hit-flow.png)
458+
459+
### Hardware Topology
460+
461+
Single-Pi primary hardware topology with optional legacy dual-Pi support:
462+
463+
![PiTrac hardware topology](assets/images/hardware-topology.png)
464+
465+
### Module Dependencies
466+
467+
Current module dependency map for runtime libraries and entrypoints:
468+
469+
![PiTrac module dependencies](assets/images/module-dependencies.png)
470+
471+
### Calibration Flows
472+
473+
Auto-calibration process for each camera:
474+
475+
![PiTrac camera1 calibration flow](assets/images/calibration-flow-camera1.png)
476+
477+
![PiTrac camera2 calibration flow](assets/images/calibration-flow-camera2.png)
478+
479+
## Simulator Data
480+
481+
- Runtime shot results are emitted through the ActiveMQ topic `Golf.Sim`.
482+
- GSPro integration uses `sim/common` and `sim/gspro` with TCP output to GSPro (default port `921`).
483+
- Result/debug images are written to the configured web share and logging directories (for example `~/LM_Shares/Images` and `~/PiTracLogs`).
484+
485+
## Licensing
486+
487+
This repository is mixed-license and uses file-level SPDX identifiers.
488+
489+
### License Files
490+
491+
- MIT: [`LICENSE`](LICENSE)
492+
- GPL-2.0-only: [`LICENSES/GPL-2.0-only.txt`](LICENSES/GPL-2.0-only.txt)
493+
- BSD-2-Clause: [`LICENSES/BSD-2-Clause.txt`](LICENSES/BSD-2-Clause.txt)
494+
- Repository notice: [`NOTICE`](NOTICE)
495+
496+
### File-Level SPDX Rules
497+
498+
- The SPDX header on each file is the source of truth for that file's license.
499+
- Preserve upstream/third-party notices in derived files.
500+
- Net-new Digital Hand code should use MIT headers.
501+
- Contributor policy: [`LICENSE_POLICY.md`](LICENSE_POLICY.md)
502+
- Header templates: [`COPYRIGHT_HEADERS.md`](COPYRIGHT_HEADERS.md)
503+
504+
## Additional Resources
505+
506+
- Build internals: [`BUILD_SYSTEM.md`](BUILD_SYSTEM.md)
507+
- Developer workflows: [`DEVELOPER_QUICKSTART.md`](DEVELOPER_QUICKSTART.md)
508+
- Hook setup: [`hooks/README.md`](hooks/README.md)
509+
- Diagram sources: `assets/diagram/*.puml`
Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,69 @@
11
@startuml
2-
title PiTrac Architecture (Services + Runtime Components)
2+
title PiTrac-Light Runtime Architecture (Refactored)
33

44
skinparam shadowing false
55
skinparam backgroundColor white
66
skinparam componentStyle rectangle
77
skinparam packageStyle rectangle
88
skinparam defaultTextAlignment center
99

10-
actor "User" as user
10+
actor "Operator" as user
1111

1212
node "Raspberry Pi OS (arm64)" as pi {
13-
package "systemd Services" {
14-
[pitrac-web.service] as websvc
15-
[activemq.service] as amqsvc
13+
package "CLI and Operations" {
14+
[pitrac-cli] as cli
15+
[RunScripts\n(src/RunScripts/*.sh)] as scripts
1616
}
1717

18-
package "Web Layer (Python FastAPI)" as web {
19-
[Browser UI\nDashboard/Calibration/Testing] as browser
20-
[REST API + WebSocket\nserver.py] as api
21-
[PiTracProcessManager\n(pitrac_manager.py)] as procman
22-
[CalibrationManager] as calman
23-
[ActiveMQ Listener\n(STOMP 61613)] as stlistener
24-
[ShotDataStore + Parser] as datastore
25-
[ConfigurationManager] as cfgman
18+
package "Launch Monitor Runtime (C++)" {
19+
[pitrac_lm\n--system_mode camera1\nFSM + hit detection] as cam1
20+
[pitrac_lm\n--system_mode camera2\ntriggered capture] as cam2
21+
[ConfigurationManager\n(JSON + env overrides)] as cfgmgr
22+
[ActiveMQ IPC Adapter\nproducer + consumer] as ipc
23+
[Simulator Bridge\nsim/common + sim/gspro] as sim
24+
[Artifact Writer\nGsUISystem + LoggingTools] as artifactsvc
2625
}
2726

28-
package "Core LM Runtime (C++ pitrac_lm)" as lm {
29-
[Camera1 Process\nFSM + hit detection] as cam1
30-
[Camera2 Process\ncapture/IPC responder] as cam2
31-
[IPC System\n(OpenWire producer/consumer)] as ipc
32-
[Simulator Interfaces\nGSPro TCP sockets] as simsock
33-
}
34-
35-
database "ActiveMQ Broker\nOpenWire 61616 / STOMP 61613" as amq
27+
database "ActiveMQ Broker\nOpenWire tcp://*:61616\nTopic: Golf.Sim" as amq
3628

37-
folder "~/.pitrac/config" as cfgfiles
38-
folder "~/.pitrac/logs + ~/.pitrac/run" as runtimedirs
39-
folder "~/LM_Shares/Images" as images
29+
folder "~/.pitrac/config\npitrac.env\nuser_settings.json\ngolf_sim_config.json" as cfg
30+
folder "~/LM_Shares/Images\n~/PiTracLogs" as files
4031
}
4132

4233
cloud "Simulator PC" as simpc {
4334
[GSPro] as gspro
4435
}
4536

46-
user --> browser
47-
browser --> api : HTTP :8080\nREST + /ws
37+
cloud "Optional External Tools" as external {
38+
[Golf.Sim topic subscriber\n(OpenWire/CMS)] as sub
39+
}
4840

49-
websvc --> api : starts uvicorn main.py
50-
amqsvc --> amq : broker runtime
41+
user --> cli : setup / run / service
42+
user --> scripts : optional direct execution
5143

52-
api --> procman
53-
api --> calman
54-
api --> cfgman
55-
api --> stlistener
56-
stlistener --> datastore
57-
datastore --> api : websocket broadcasts
44+
cli --> cfg : env setup + config init
45+
cli --> amq : broker checks / service control
46+
cli --> cam1 : launch camera1 modes
47+
cli --> cam2 : launch camera2 modes
5848

59-
procman --> cam1 : spawn/stop process
60-
procman --> cam2 : spawn/stop process\n(single-Pi mode)
61-
procman --> cfgman : generate config + CLI/env
62-
procman --> runtimedirs : PID/log files
49+
scripts --> cam1
50+
scripts --> cam2
6351

64-
cfgman --> cfgfiles : user_settings.json\ncalibration_data.json\ngenerated_golf_sim_config.json
52+
cam1 --> cfgmgr
53+
cam2 --> cfgmgr
54+
cfgmgr --> cfg : load + persist config values
6555

6656
cam1 --> ipc
6757
cam2 --> ipc
68-
ipc --> amq : topic Golf.Sim
69-
stlistener --> amq : subscribe /topic/Golf.Sim
58+
ipc --> amq : publish / consume IPC messages
59+
60+
cam1 --> sim : shot metrics
61+
sim --> gspro : TCP :921
7062

71-
cam1 --> simsock
72-
simsock --> gspro : TCP 921
63+
cam1 --> artifactsvc
64+
cam2 --> artifactsvc
65+
artifactsvc --> files : write PNGs + logs
7366

74-
cam1 --> images : shot/debug images
75-
cam2 --> images : capture images
76-
api --> images : /images + /api/images
67+
amq --> sub : status / hit / control messages
7768

7869
@enduml
Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@startuml
2-
title PiTrac Camera 1 Calibration Flow
2+
title Camera 1 Auto-Calibration Flow (Current Runtime)
33

44
skinparam shadowing false
55
skinparam backgroundColor white
@@ -12,27 +12,28 @@ skinparam activity {
1212

1313
start
1414

15-
:Optional pre-check:\nPOST /api/calibration/ball-location/camera1;
16-
:Optional still capture:\nPOST /api/calibration/capture/camera1;
17-
:Validate image quality in\n~/LM_Shares/Images;
15+
:Ensure runtime prerequisites:\n- pitrac-cli validate env\n- pitrac-cli service broker start;
16+
:Optional image sanity check:\npitrac-cli run still --camera 1;
1817

19-
:POST /api/calibration/auto/camera1;
20-
:CalibrationManager creates session\nfor expected keys:\n- gs_config.cameras.kCamera1FocalLength\n- gs_config.cameras.kCamera1Angles;
21-
:Launch pitrac_lm\n--system_mode=camera1AutoCalibrate\n(+ --run_single_pi in single mode);
18+
:Run auto-calibration:\npitrac-cli run auto-calibrate --camera 1;
19+
:CLI launches pitrac_lm with\n--system_mode camera1AutoCalibrate\nand common args;
2220

23-
:Hybrid completion detection:\n1) API callbacks\n2) Process exit\n3) Timeout (40s);
21+
:pitrac_lm startup:\nload config + init camera + IPC + GPIO;
2422

25-
if (Both callback keys received?) then (yes)
26-
:PUT /api/config updates camera1\nfocal length + angles;
27-
:Write values into\n~/.pitrac/config/calibration_data.json;
28-
:Regenerate\n~/.pitrac/config/generated_golf_sim_config.json;
23+
:Capture multiple samples\n(kNumberPicturesForFocalLengthAverage);
24+
:Compute average focal length;
25+
26+
if (Ball detection / focal length valid?) then (yes)
27+
:Determine camera angles;
28+
:Update config tree keys:\n- gs_config.cameras.kCamera1FocalLength\n- gs_config.cameras.kCamera1Angles;
29+
:Backup current config file;
30+
:Write updated golf_sim_config.json;
31+
:Save calibration artifacts\nto logging/image directories;
32+
:Exit success;
2933
else (no)
30-
:Fallback to process result\nand output parsing for failure markers;
34+
:Abort calibration with error logs;
35+
:Keep previous effective values;
3136
endif
3237

33-
:Status exposed via\nGET /api/calibration/status;
34-
:Calibration values exposed via\nGET /api/calibration/data;
35-
:Validate resulting calibration images\nin ~/LM_Shares/Images;
36-
3738
stop
3839
@enduml

0 commit comments

Comments
 (0)