This document is the single source of truth for development conventions in this repository, intended for all engineering maintainers and team developers.
| Role | Responsibility |
|---|---|
| kevinlasnh | Defines requirements, makes final decisions, executes on-vehicle tests, reviews PRs |
| Claude | Architecture, research, solution design, result review |
| Codex | Implementation execution, build verification, commits, PRs, documentation sync |
| Team developers | Collaborate under the same branch and PR rules |
- Understand the chain before modifying code or parameters.
- Do not modify the primary operating chain without verifying the impact scope.
- Upstream dependencies are fetched through
dependencies.repos+vcs import; this repository does not maintain asrc/third_party/directory. - Critical modifications must explain what, why, and risk.
- Do not modify code directly on the vehicle (Jetson). The standard flow is: modify code in your local repository on your own computer -> push to your branch on GitHub -> pull that branch on the vehicle -> build and deploy on the vehicle. The Jetson is only for compiling, running, and testing.
The following flow is the standard workflow for all team developers. Each step indicates whether AI usage is allowed.
SSH into the Jetson, check repository and hardware status:
ssh jetson@100.97.227.24
cd ~/XJTLU-autonomous-vehicle
git status
git checkout main
git pull --ff-only
source install/setup.bashFirst-time deployment or new machine initialization:
make setup
make build
source install/setup.bash
bash scripts/init_runtime_data.shManually check hardware status:
# Check LiDAR (Livox MID360)
ls /dev/ttyUSB* /dev/ttyACM*
ros2 topic echo /livox/lidar --once
# Check GPS
ros2 topic echo /fix --once
# Check IMU (BMI088, integrated in RM C Board)
ros2 topic echo /imu --once
# Check STM32 serial port
ls /dev/stm32_boardConfirm all hardware is functioning before starting work.
After kevinlasnh assigns a task, create a new branch from the latest main, or switch to an existing working branch:
# New task: create new branch
git checkout -b gps-route-collector
# Continue existing task: switch to existing branch and sync
git checkout your-branch
git pull origin your-branchBranch naming uses descriptive names directly, without prefixes:
- Examples:
gps,nav-tuning,lidar-fix,docs-sync
- kevinlasnh assigns a task with clear content and deadline.
- Developer creates a new branch from the latest
main, named after the task. - Develop and test on your own branch (including on-vehicle testing).
- Submit a PR once the feature is complete and tests pass.
- kevinlasnh reviews and approves, then merge into
main. - Delete the branch after merging.
One branch per task. Do not mix unrelated work in a single branch.
Before writing any code, you must complete the following research:
- Read code: Read all source files related to the task, understand the current data flow and call chain.
- Read documentation: Read relevant docs in
docs-EN/ordocs-CN/(architecture, knowledge, devlog, etc.), understand historical decisions and current constraints. - Read parameters: Check
master_params.yamland related YAML configs, confirm current parameter values. - Read launch chain: Trace the complete launch chain from
Makefile'slaunch-*entries, understand node startup order and dependencies. - Design a plan: Based on the above research, formulate your implementation plan.
AI is prohibited in this step. The purpose is to ensure you truly understand the code and system, rather than relying on AI summaries.
Organize your plan into a document containing:
- Which files to modify, what changes to make
- Why make these changes
- Expected impact scope (which nodes, which operating modes are affected)
- Risk points
Submit your plan to AI for review (Claude, ChatGPT, or other tools), have AI check:
- Whether the plan has gaps
- Whether there is a better implementation approach
- Whether it would introduce side effects
After review, send the final plan to kevinlasnh for confirmation. Do not begin coding until kevinlasnh confirms.
Before coding, evaluate the plan for deployability:
- Can the changes compile successfully on the Jetson?
- Will it break the existing launch chain?
- Are new dependencies needed? If so, are
package.xmlandCMakeLists.txtboth updated? - Are parameter changes correctly propagated in
master_params.yaml?
AI can be used in this step to help check plan deployability.
Modify code in your local repository on your own computer:
- First verify the actual code state, launch chain, and current parameters.
- Then make changes -- do not write from historical memory alone.
- If changes affect system behavior, first confirm which operating modes are impacted.
- When adding new launch files / modes / parameter profiles, update documentation concurrently rather than leaving it for later.
# On your local computer
git add path/to/file1 path/to/file2
git commit -m "Explain what changed and why"
git push -u origin your-branch
# SSH into Jetson
ssh jetson@100.97.227.24
cd ~/XJTLU-autonomous-vehicle
git checkout your-branch
git pull origin your-branch
colcon build --packages-select <pkg> --symlink-install --parallel-workers 1
source install/setup.bashCommit rules:
- Only add specific files. Do not use
git add -Aorgit add .. - Do not commit unrelated changes.
- Commit messages must be in English, stating what changed and why.
Build rules:
--parallel-workers 1is a hard requirement (Jetson memory constraint).source install/setup.bashmust be re-executed after every build.- Python packages can skip rebuilding under
--symlink-install, but runtime verification is still required. build-navigationcurrently includeswaypoint_collector,waypoint_nav_tool,gps_waypoint_dispatcher.- After modifying
CMakeLists.txtor install rules, confirm that target files actually exist ininstall/.
Launch the system in the appropriate mode based on the scope of changes:
make launch-slam
make launch-explore
make launch-indoor-nav
make launch-explore-gps
make launch-nav-gps
make launch-corridor
make launch-travelAt minimum, verify the following:
- All relevant nodes are online
- Key topics / actions have data
map -> odom -> base_linkTF chain is complete- Session logs are landing in
~/XJTLU-autonomous-vehicle/runtime-data/logs/latest/
If system verification fails, go back to Step 6 to fix the code, loop until it passes.
After system verification passes, conduct on-vehicle testing:
- Before testing: Confirm the PS2 gamepad is available, someone is always ready to press
Xto disable motors. - During testing: Observe vehicle physical behavior, record anomalies (yaw drift, stalls, collision risks, etc.).
- After testing:
- Record the physical assessment results
- Record the test session path (e.g.,
runtime-data/logs/2026-04-16-14-30-00/) - Record improvement suggestions
After every on-vehicle test, logs must be analyzed. You can analyze manually or with AI assistance.
# Find the latest log directory
LATEST_LOG=$(ls -td ~/XJTLU-autonomous-vehicle/runtime-data/logs/*/ 2>/dev/null | head -1)
# View bag summary
ros2 bag info ${LATEST_LOG}bag/
# Extract topic statistics from .db3 using sqlite3
python3 -c "
import sqlite3, glob
db = glob.glob('${LATEST_LOG}bag/*.db3')[0]
conn = sqlite3.connect(db)
for row in conn.execute('SELECT t.name, COUNT(m.id) FROM messages m JOIN topics t ON m.topic_id=t.id GROUP BY t.name'):
print(f'{row[0]}: {row[1]} msgs')
conn.close()
"Mandatory data points to check (after every on-vehicle test):
| Data Point | Source Topic | What to Look For |
|---|---|---|
| Total run duration | bag metadata | Whether it completed normally |
| GPS fix quality | /fix |
fix type, satellite count, interruptions |
| Corridor status sequence | /gps_corridor/status |
Whether all states completed as expected |
| Goal positions | /gps_corridor/goal_map |
Deviation from expected targets |
| Velocity commands | /cmd_vel |
Abnormal stalls (vel=0 lasting >3s) |
| TF continuity | /tf |
map->odom->base_link jumps |
| Path planning | /plan |
Whether path is reasonable, excessive replanning |
Based on test results and log analysis, assess the problem type yourself:
- Architecture issue (data flow design error, incorrect node responsibility division, etc.): Stop work, report to kevinlasnh, wait for redesign.
- Minor issue (parameter adjustment needed, edge case not handled, small bug, etc.): Fix it yourself, loop back to Step 6.
- PASS (feature meets expectations, tests passed): Proceed to Step 12.
AI is prohibited for this assessment. The purpose is to develop your own understanding and judgment of the system. If unsure about an issue, consult kevinlasnh.
Once the feature is complete and tests pass:
gh auth status
gh pr createPRs must clearly describe:
- What was changed
- Why it was changed
- How it was tested (include session path and key test conclusions)
- Which layers are affected
All PRs must be reviewed and approved by kevinlasnh before merging into main.
After merging:
gh pr merge --merge --delete-branch
git checkout main
git pull --ff-only
git fetch --pruneIf gh auth status on the Jetson fails, you can run PR operations on a trusted workstation already logged into GitHub CLI for the same branch, then have the Jetson git pull to sync.
Before the end of your work day, push test runtime-data to Hugging Face:
cd ~/XJTLU-autonomous-vehicle/runtime-data
git add logs/<your-session-directory>/ gnss/current_route.yaml
git commit -m "Add test session YYYY-MM-DD-HH-MM-SS"
git push origin mainIf git push fails, ask kevinlasnh for help.
Update the day's work documentation following the Devlog Documentation Format. One copy in Chinese and one in English, with matching content.
AI can be used to assist with documentation writing, but you must ensure accuracy and format compliance.
If you need to pause work midway (end of day, break, etc.), you must ensure:
- Current progress is not lost (code is committed and pushed to your branch).
- You can pick up where you left off next time.
The specific tool or method for recording progress is up to you (notes, TODO files, branch descriptions, etc.), as long as no progress is lost.
| Step | AI Allowed? |
|---|---|
| Session initialization (hardware checks, etc.) | Prohibited |
| Research, reading code, understanding current state | Prohibited |
| Plan review | Allowed |
| Deployability review | Allowed |
| Coding | Not recommended |
| Build and system verification | Prohibited |
| On-vehicle testing | Prohibited |
| Log analysis | Allowed |
| Problem assessment and escalation | Prohibited |
| Documentation writing | Allowed |
Every team member must push to their branch at least once before the end of their work day, updating project documentation (progress, notes, etc.). As long as any work was done that day (no matter how small), documentation updates are mandatory. If no work was done at all that day, no update is required.
All devlog entries must follow the format below. One copy in Chinese and one in English (docs-CN/devlog/YYYY-MM.md + docs-EN/devlog/YYYY-MM.md), with matching content.
## YYYY.MM.DD
### [Change Topic Title]
- One-line summary of the change
- Specific parameter values, commit hash (e.g., `abc1234`), file namesWhen changes involve multiple files or require design decision explanations, use the four-element format:
#### Subtopic Name (`commit hash`)
- **File**: specific file path
- **Change**: what was done
- **Reason**: why it was done
- **Effect**: what impact it produces- Date format is
YYYY.MM.DD. - Each topic uses
### [Square Bracket Title]. - Reference specific commit hashes, parameter values (including old and new values), and file paths.
- No vague descriptions (e.g., "optimized performance"). Must specify exactly what parameter changed, from what value to what value.
- When multiple changes are involved, split into subtopics, each with its own four-element block.
- Test results must include: test session path, key findings, user decisions.
If changes involve nav-gps, at minimum add these checks:
- Whether
build_scene_runtime.pysuccessfully generatescurrent_scene/compiled artifacts - Whether
gps_anchor_localizerentersNAV_READY - Whether
gps_waypoint_dispatchersuccessfully readsscene_points.yaml - Whether
/compute_route//follow_path//navigate_to_poseactions are online - Whether
goto_name/list_destinations/stopbehave correctly - Whether mock / replay
/fixcan be used for software smoke testing when there is no live fix indoors
When the task objective narrows to "fixed launch position -> GPS route endpoint" corridor verification, prefer using:
- Collect corridor multi-waypoint route:
python3 scripts/collect_gps_route.py
- Return the vehicle to the fixed Launch Pose, align the heading
- Launch directly:
make launch-corridor- or
bash scripts/launch_with_logs.sh corridor
- Observe:
/gps_corridor/status
gps_global_aligner_node+gps_route_runner_nodeautomatically:- Standalone aligner estimates smoothed
ENU->maptransform - Checks whether current
/fixis close tostart_ref - Bootstrap startup (
yaw0 + launch_yaw_deg) - GPS waypoints -> ENU -> map conversion
- Freeze alignment within waypoint, split subgoals per segment
- Sequential
NavigateToPose
- Standalone aligner estimates smoothed
This workflow no longer requires:
nav_gps_menu.pygoto_nameroute_serverscene_gps_bundle.yaml
- Modifying already-tuned YAML parameters without a documented reason is not allowed.
- Parameter changes must be simultaneously recorded in the relevant documentation.
- The current unified parameter entry point is
src/bringup/config/master_params.yaml. - Nav2 primary configuration files are:
nav2_default.yamlnav2_explore.yamlnav2_travel.yaml
Runtime data lives inside the workspace at ~/XJTLU-autonomous-vehicle/runtime-data/:
~/XJTLU-autonomous-vehicle/runtime-data/
├── config/
├── gnss/
├── logs/
│ ├── <timestamp>/
│ │ ├── console/
│ │ ├── data/
│ │ └── system/
│ └── latest -> <timestamp>
├── maps/
├── perf/
└── planning/
Additional rules:
make launch-*automatically creates session log directories.console/stores ROS 2 console logs.data/stores per-node custom logs, driven byFYP_LOG_SESSION_DIR.system/storestegrastats.logandsession_info.yaml.- When using
ros2 launchdirectly, some legacy log fallback paths may still exist, such aslogs/twist_log/.
- The current GNSS stack operates at basic GPS accuracy level, not maintained as an RTK workflow.
- Indoors without satellite reception,
/fixshowingstatus=-1orNaNis expected behavior. gnss_calibrationdoes not write a validgnss_offset.txtunder no-fix conditions.- On the current Jetson runtime,
~/XJTLU-autonomous-vehicle/runtime-data/gnss/may containgnss_offset.invalid_*.txtas invalid sample traces.
- The PS2 gamepad must always be kept available.
- During autonomous driving, someone must always be ready to press the
Xbutton to disable motors. - The red emergency stop button on the vehicle body always takes priority over software commands.
- The
Bbutton is prohibited as an emergency braking method because it causes severe wheel reversal.
- The current Jetson wired connection
Wired connection 1is set to auto-connect with priority100; do not disable it casually. - Check
gh auth statuson the machine performing PR operations. - If the Jetson's
ghlogin session expires, PRs and merges can be completed on a local workstation already logged into GitHub CLI, then have the Jetson pullmainback.
kevinlasnh uses Claude + Codex + Gemini for AI-assisted development, with the control plane maintained in a separate repository. Team developers do not need to know this workflow -- follow the Standard Development Flow in this document.
When code, launch files, parameters, system environment, or workflows change, corresponding documentation must be updated. Both CN and EN documentation directories must be updated simultaneously.
| Change Type | Minimum Documentation to Sync |
|---|---|
| Node source code | devlog, related knowledge, architecture.md when necessary |
| Launch files | devlog, commands.md, architecture.md when necessary |
| YAML parameters | devlog, corresponding knowledge document |
| Scripts and tools | devlog, commands.md |
| Bug fixes / new bugs | devlog, known_issues.md |
| System environment changes | devlog, commands.md |
| New/removed ROS2 packages | devlog, architecture.md, commands.md |
| Hardware changes | devlog, architecture.md, known_issues.md |
| GPS/GNSS related | devlog, gps_planning.md, pgo.md |
| Physical test conclusions | devlog, nav2_tuning.md, known_issues.md |
Most common sync targets:
docs-CN/devlog/YYYY-MM.md+docs-EN/devlog/YYYY-MM.mddocs-CN/commands.md+docs-EN/commands.mddocs-CN/architecture.md+docs-EN/architecture.mddocs-CN/known_issues.md+docs-EN/known_issues.mddocs-CN/knowledge/*.md+docs-EN/knowledge/*.md
A session is not considered closed until all of the following are complete:
- Changes have been verified.
- Related documentation has been synced.
- Branch has been pushed.
- PR has been created and merged, or there is a clear record of why only a feature branch was left.
- Jetson is back on the latest
main, or there is a clear record of the current branch and reason for staying. - If there are new system facts, issues, or blockers, they have been written to the development log and issue tracker.
- YAML parameter changes must document the reason.
- Builds must use
--parallel-workers 1. source install/setup.bashmust be re-executed after every build.- Upstream dependencies fetched through
dependencies.reposare not treated as project custom development areas. - Documentation descriptions must reflect the current executable state, not historical conventions.