-
-
Notifications
You must be signed in to change notification settings - Fork 0
Finish task 1 UI #59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Finish task 1 UI #59
Changes from all commits
56ed891
296cebc
8886d77
b6de82f
535dc71
06df111
ef9532f
55429ee
4b9261f
5085f6b
bc398ac
076b269
1b6bdf5
68b612d
fb2ccf9
fc5fa21
32665c4
9bfe0dc
87f73fa
b39e136
9579530
33e2668
a185933
5e40baf
87a43dd
8aeedef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,3 +10,5 @@ | |
| projects/web-backend/src/db.sqlite3-journal | ||
| /.idea | ||
| *.rdb | ||
|
|
||
| */.venv | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,37 +1,37 @@ | ||
| repos: | ||
| - repo: https://github.com/pre-commit/pre-commit-hooks | ||
| - repo: https://github.com/pre-commit/pre-commit-hooks | ||
| rev: v4.5.0 | ||
| hooks: | ||
| - id: end-of-file-fixer | ||
| - id: trailing-whitespace | ||
| - id: check-added-large-files | ||
| args: ['--maxkb=500'] | ||
| - id: check-merge-conflict | ||
| - id: debug-statements | ||
| - id: check-case-conflict | ||
| - repo: https://github.com/astral-sh/ruff-pre-commit | ||
| - id: end-of-file-fixer | ||
| - id: trailing-whitespace | ||
| - id: check-added-large-files | ||
| args: ["--maxkb=500"] | ||
| - id: check-merge-conflict | ||
| - id: debug-statements | ||
| - id: check-case-conflict | ||
| - repo: https://github.com/astral-sh/ruff-pre-commit | ||
| rev: v0.8.4 | ||
| hooks: | ||
| - id: ruff | ||
| args: [ --fix ] | ||
| - id: ruff-format | ||
| - repo: local | ||
| - id: ruff | ||
| args: [--fix] | ||
| - id: ruff-format | ||
| - repo: local | ||
| hooks: | ||
| - id: eslint | ||
| - id: eslint | ||
| name: eslint | ||
| entry: bash -c 'cd projects/web-frontend && npm run lint' | ||
| language: system | ||
| files: projects/web-frontend/.*\.[jt]sx?$ | ||
| pass_filenames: false | ||
| - id: generate-web-backend-api-spec | ||
| - id: generate-web-backend-api-spec | ||
| name: Generate Web Backend API Spec | ||
| entry: bash -c 'cd projects/web-backend && venv/bin/python src/manage.py spectacular --file api_spec.yaml --validate' | ||
| entry: bash -c 'cd projects/web-backend && .venv/bin/python src/manage.py spectacular --file api_spec.yaml --validate' | ||
| language: system | ||
| files: ^projects/web-backend/ | ||
| pass_filenames: false | ||
| - id: generate-mp-api-spec | ||
| - id: generate-mp-api-spec | ||
| name: Generate Mission Planner API Spec | ||
| entry: bash -c 'cd projects/mission-planner && venv/bin/python generate_spec.py' | ||
| entry: bash -c 'cd projects/mission-planner && .venv/bin/python generate_spec.py' | ||
| language: system | ||
| files: ^projects/mission-planner/ | ||
| pass_filenames: false |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Software Preflight Setup | ||
|
|
||
| ## DRONE | ||
|
|
||
| - [ ] Insert LTE Board into miniPCIe module | ||
| - [ ] Insert SIM Card into LTE Board | ||
| - Hold it upside down to let gravity help you insert | ||
| - [ ] Attach antenna to LTE board | ||
| - > **TODO:** UPDATE HERE ABOUT CORRECT PORTS | ||
| - [ ] Attach Jetson to drone | ||
| - [ ] Attach camera to mount | ||
| - [ ] Connect power to Jetson | ||
| - [ ] Connect camera to Jetson | ||
|
|
||
| --- | ||
|
|
||
| ## GCOM / PC | ||
|
|
||
| - [ ] Connect radio transmitter to thinkpad computer | ||
| - Remember to put arrow to 1 (bottom pin row) on wire | ||
| - [ ] Create 2 Terminal tabs for GCOM and Mavproxy | ||
| - [ ] Start `mavproxy.py` with port forwarding for Mission Planner and GCOM | ||
| - > **TODO:** Add command here | ||
| - [ ] Start Mission Planner and connect to mavproxy | ||
| - [ ] Start GCOM with startup script for all 3 services | ||
| - **CHECK:** Ensure all three tmux windows have no errors | ||
| - [ ] Start WebRTC signalling server with script + ngrok | ||
| - Potentially update to new IP on server | ||
| - [ ] Check GCOM frontend to see if drone made connection | ||
|
|
||
| --- | ||
|
|
||
| ## JETSON | ||
|
|
||
| - [ ] SSH onto system | ||
| - [ ] Run `docker compose up -d` in `hawkeye-os` repo to start ROS container | ||
| - **CHECK:** Check logs to see if container is running properly |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,5 @@ | ||
| __pycache__ | ||
| *.pyc | ||
| venv | ||
| src.egg-info | ||
| src/fence_test.py | ||
| poetry.lock | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ | |
| *.pyc | ||
| /.idea | ||
| files/ | ||
| oldc_sessions/ | ||
| odlc_sessions/ | ||
|
|
||
| dump.rdb | ||
| **/.DS_Store | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| # This is chosen by me (mercury), might need to change. | ||
| FLT_EPSILON = 1e-6 | ||
|
|
||
| # Fixed camera intrinsics (Brown-Conrady / plumb_bob model) | ||
| # Values from: ros2 topic echo /camera/camera/color/camera_info (1280x720) | ||
| CAMERA_INTRINSICS = { | ||
| 'fx': 643.2360229492188, | ||
| 'fy': 642.1893920898438, | ||
| 'ppx': 661.8545532226562, | ||
| 'ppy': 365.9696044921875, | ||
| } | ||
|
|
||
| # Brown-Conrady distortion coefficients [k1, k2, p1, p2, k3] | ||
| # Values from: ros2 topic echo /camera/camera/color/camera_info (1280x720) | ||
| DISTORTION_COEFFS = [ | ||
| -0.05651168152689934, | ||
| 0.06660270690917969, | ||
| -0.00015544862253591418, | ||
| 0.0008432056056335568, | ||
| -0.02149238809943199, | ||
| ] | ||
|
|
||
|
|
||
| def _is_distortion_zero(coeffs: list[float]) -> bool: | ||
| return all(abs(c) < FLT_EPSILON for c in coeffs) | ||
|
|
||
|
|
||
| def deproject_pixel_to_point( | ||
| pixel: list[float], depth: float) -> list[float]: | ||
| """Deproject a 2D pixel coordinate to a 3D point using Brown-Conrady distortion model. | ||
|
|
||
| Re-implemented from https://github.com/realsenseai/librealsense/blob/78cb605b11f5ba80176e7b8d70292f76ba625565/src/rs.cpp#L4273 | ||
| """ | ||
| fx = CAMERA_INTRINSICS["fx"] | ||
| fy = CAMERA_INTRINSICS["fy"] | ||
| ppx = CAMERA_INTRINSICS["ppx"] | ||
| ppy = CAMERA_INTRINSICS["ppy"] | ||
| coeffs = DISTORTION_COEFFS | ||
|
|
||
| x = (pixel[0] - ppx) / fx | ||
| y = (pixel[1] - ppy) / fy | ||
|
|
||
| xo = x | ||
| yo = y | ||
|
|
||
| if not _is_distortion_zero(coeffs): | ||
| for _ in range(10): | ||
| r2 = x * x + y * y | ||
| icdist = 1.0 / ( | ||
| 1 + ((coeffs[4] * r2 + coeffs[1]) * r2 + coeffs[0]) * r2) | ||
| delta_x = 2 * coeffs[2] * x * y + coeffs[3] * (r2 + 2 * x * x) | ||
| delta_y = 2 * coeffs[3] * x * y + coeffs[2] * (r2 + 2 * y * y) | ||
| x = (xo - delta_x) * icdist | ||
| y = (yo - delta_y) * icdist | ||
|
|
||
| return [depth * x, depth * y, depth] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,19 @@ | ||
| from django.urls import include, path | ||
| from rest_framework.routers import DefaultRouter | ||
|
|
||
| from .views import GroundObjectViewset, ImageViewset, save_oldc_session | ||
| from .views import ( | ||
| GroundObjectViewset, | ||
| ImageViewset, | ||
| deproject_pixel, | ||
| save_odlc_session, | ||
| ) | ||
|
|
||
| router = DefaultRouter() | ||
| router.register(r"image", ImageViewset, basename="image") | ||
| router.register(r"groundobject", GroundObjectViewset, basename="groundobject") | ||
|
|
||
| urlpatterns = [ | ||
| path("", include(router.urls)), | ||
| path("oldc-session/save/", save_oldc_session, name="save_oldc_session"), | ||
| path("odlc-session/save/", save_odlc_session, name="save_odlc_session"), | ||
| path("deproject-pixel/", deproject_pixel, name="deproject_pixel"), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,14 +8,48 @@ | |
| from rest_framework import viewsets | ||
|
|
||
| from .models import GroundObject, Image | ||
| from .projection import deproject_pixel_to_point | ||
| from .serializers import GroundObjectSerializer, ImageSerializer | ||
|
|
||
| OLDC_SESSIONS_DIR = Path(__file__).resolve().parent.parent.parent / "oldc_sessions" | ||
| ODLC_SESSIONS_DIR = Path(__file__).resolve().parent.parent.parent / "odlc_sessions" | ||
|
|
||
|
|
||
| @csrf_exempt | ||
| @require_http_methods(["POST"]) | ||
| def save_oldc_session(request): | ||
| def deproject_pixel(request): | ||
| try: | ||
| data = json.loads(request.body) | ||
| pixel = data.get("pixel") | ||
| depth = data.get("depth") | ||
|
|
||
| if not isinstance(pixel, list) or len(pixel) != 2: | ||
| return JsonResponse( | ||
| {"error": "Invalid input: pixel must be a list of 2 floats"}, status=400 | ||
| ) | ||
|
|
||
| if not isinstance(depth, (int, float)): | ||
| return JsonResponse( | ||
| {"error": "Invalid input: depth must be a float"}, status=400 | ||
| ) | ||
|
|
||
| point = deproject_pixel_to_point( | ||
| pixel=pixel, depth=float(depth) | ||
| ) | ||
|
|
||
| return JsonResponse({"point": point}) | ||
|
Comment on lines
17
to
+39
|
||
| except (ValueError, NotImplementedError) as e: | ||
| return JsonResponse({"error": str(e)}, status=400) | ||
| except (KeyError, TypeError) as e: | ||
| return JsonResponse({"error": "Invalid input", "details": str(e)}, status=400) | ||
| except Exception as e: | ||
| return JsonResponse( | ||
| {"error": "Internal server error", "details": str(e)}, status=500 | ||
| ) | ||
|
|
||
|
|
||
| @csrf_exempt | ||
| @require_http_methods(["POST"]) | ||
| def save_odlc_session(request): | ||
| try: | ||
| data = json.loads(request.body) | ||
| session_id = data.get("sessionId") | ||
|
|
@@ -24,14 +58,15 @@ def save_oldc_session(request): | |
| if not session_id or not isinstance(images, list): | ||
| return JsonResponse({"error": "Invalid input"}, status=400) | ||
|
|
||
| OLDC_SESSIONS_DIR.mkdir(exist_ok=True) | ||
| session_file = OLDC_SESSIONS_DIR / f"{session_id}.json" | ||
| ODLC_SESSIONS_DIR.mkdir(exist_ok=True) | ||
| session_file = ODLC_SESSIONS_DIR / f"{session_id}.json" | ||
| session_file.write_text(json.dumps({"sessionId": session_id, "images": images})) | ||
|
|
||
| return HttpResponse(status=200) | ||
| except (KeyError, ValueError, TypeError) as e: | ||
| return JsonResponse({"error": "Invalid input", "details": str(e)}, status=400) | ||
| except Exception as e: | ||
| print(f"Error saving ODLC session: {e}") | ||
| return JsonResponse( | ||
| {"error": "Internal server error", "details": str(e)}, status=500 | ||
| ) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deproject_pixel_to_pointaccepts anintrinsicsdict, but the distortion coefficients are always taken from the module-levelDISTORTION_COEFFSconstant (the caller-providedcoeffs/modelare ignored). This makes the API misleading and will produce incorrect results if intrinsics/distortion differ per device. Either honor caller-provided distortion coefficients (with validation) or remove/rename the parameter to reflect that distortion is fixed server-side.