Skip to content

Jkdxbns/Frame-Simulator

Repository files navigation

Frames Simulator

A desktop GUI tool to visualize and understand 3D coordinate frames, their parent-child hierarchies, and transformations using a simple DSL. Built with PySide6 and VisPy.

Project Tree

FramesSim_v8/
├─ AXIS_LABELS_GUIDE.md
├─ dsl_parser.py
├─ frame_visual.py
├─ frames_model.py
├─ main.py
├─ math_se3.py
├─ README.md  ← you are here
├─ ui_helper_functions.py
└─ ui_main_window.py

What this app does

  • Visualizes coordinate frames as RGB axes (X=Red, Y=Green, Z=Blue)
  • Lets you build hierarchies of frames with a root “Universe” frame (U)
  • Defines frame poses using a simple text DSL: Rot(axis, deg) and Trans(x, y, z)
  • Supports both local and world modes for rotations/translations
  • Adds points attached to frames and shows their links to parent frames
  • Animates a frame from identity to its current pose (1-second demo)
  • Provides camera controls (Home, Focus) and grid toggle
  • Optional 3‑plane reference grids (XY, XZ, YZ) that toggle together

How it works (high-level)

  • Data model (frames_model.py): keeps a dictionary of FrameNode objects, each with a parent and a local 4×4 transform. Computes world transforms by chaining parent→child.
  • DSL parser (dsl_parser.py): parses strings like Rot(z, 90) Trans(1,0,0) into tokens.
  • SE(3) math (math_se3.py): composes token lists into 4×4 matrices with selectable local/world modes for both translation and rotation.
  • Visuals (frame_visual.py): draws axes and labels using VisPy visuals; also supports point visuals.
  • UI (ui_main_window.py + ui_helper_functions.py): PySide6 window with a VisPy canvas on the left and controls on the right. Mix-in holds helper logic.
  • Entry point (main.py): wires PySide6 and VisPy and launches the app.

Architecture and main modules

1) Frames model (frames_model.py)

  • FrameNode: name, parent, tokens, local_M (4×4), and optional visual.
  • FramesModel: add_frame, set_expr, set_trans_mode, set_rot_mode, and world_M(name).
  • Universe frame U is created at startup; its transform is identity.

World transform is computed recursively:

world_M(C) = world_M(B) @ local_M(C)

2) DSL and math (dsl_parser.py, math_se3.py)

  • DSL tokens:
    • Rotation: ('rot', ('x'|'y'|'z', degrees))
    • Translation: ('trans', (x, y, z))
  • Composition rules:
    • Translation mode
      • world: M = T @ M
      • local: M = M @ T
    • Rotation mode
      • world: M = R @ M (rotate around world axes)
      • local: M = M @ R (rotate around frame axes)

3) Visuals (frame_visual.py)

  • Each frame draws three arrows (RGB) and a text label above the origin.
  • apply_transform(M) directly updates world-space positions of the arrows and label.
  • PointVisual hides the arrows and shows only a label (used for points).

4) UI (ui_main_window.py, ui_helper_functions.py)

  • Left: VisPy SceneCanvas with TurntableCamera and an optional grid.
  • Right: controls for frames list, points list, add/update/delete, mode selectors, and live matrix views for the selected frame and point.
  • Link visualization:
    • Yellow line: selected frame to its parent
    • Cyan line: selected point to its parent frame
  • UIHelperMixin centralizes: applying transforms, refreshing matrices, drawing links, and the animation step.
  • Matrices are shown using monospaced QLabel blocks (cleaner than text editors) and are selectable for copy.

Installation

  1. Create a virtual environment (recommended)
  • Windows (cmd):
python -m venv .venv
.venv\Scripts\activate
  1. Install dependencies
pip install -r requirements.txt
  1. Run the app
python main.py

If VisPy complains about backends, the app configures PySide6 via vispy_app.use_app('pyside6') in main.py.

Usage guide

  • Add a frame:
    • Enter Name, choose Parent, and type an Expr (DSL). Click “Add Frame”.
  • Update a frame:
    • Select a frame (not U), edit Expr, click “Update Selected”.
  • Delete a frame/point:
    • Select it and click the respective “Delete” button (U cannot be deleted).
  • Add a point:
    • Tools → Add Point (Ctrl+P), choose parent frame and enter translations.
  • Toggle grid:
    • Tools → Toggle Grid (Ctrl+G)
    • Shows/hides all three major planes: XY (z=0), XZ (y=0), YZ (x=0)
  • Animate selected frame:
    • Tools → Animate Selected Frame (Ctrl+A)
  • Camera:
    • View → Home (H) resets view
    • View → Focus centers the camera on the selected frame

DSL cheatsheet

  • Rotations (degrees)
    • Keywords are case-insensitive: Rot, rot, ROT all work
Rot(x, 90)
Rot(y, -45.5)
Rot(z, 180)
rot(Z, 30)
  • Translations
    • Keywords are case-insensitive: Trans, trans, TRANS all work
Trans(1, 2, 3)
trans(0.5, 0, -2)
  • Chaining
Rot(z, 90) Trans(1, 0, 0) Rot(x, 45)

Modes affect order of multiplication:

  • Translation mode = world → pre-multiply T
  • Translation mode = local → post-multiply T
  • Rotation mode = world → pre-multiply R
  • Rotation mode = local → post-multiply R

Animation

  • Animation demo interpolates a selected frame from identity to its current local transform over ~1s.
  • The rotation block is re-orthonormalized using SVD at every step to avoid drift.

Known limitations

  • Mixed-frame reference edge case: generating output may fail if one rotation/translation in an expression is intended relative to the current frame while another is explicitly relative to the Universe frame (U) within the same context. Consider sticking to a single mode per expression for now, or split operations.

Contributing / next steps

  • Add view presets (front, back, left, right, top, isometric)
  • Add saving/loading scenes (JSON)
  • Add snapping, gizmos, or manipulators in the 3D view
  • Add export of transforms/frames for other tools
  • Add tests for DSL parsing and matrix composition

Built with python using PySide6, VisPy, and NumPy.

About

A desktop GUI tool to visualize and understand 3D coordinate frames, their parent-child hierarchies, and transformations using a simple DSL. Built with PySide6 and VisPy.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages