CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pytransform3d

3D transformations for Python with comprehensive rotation representations, coordinate conversions, and visualization tools

Pending
Overview
Eval results
Files

editor.mddocs/

Editor

Interactive GUI tools for visual transformation editing using PyQt with real-time 3D visualization and parameter adjustment capabilities.

Capabilities

TransformEditor Class

Complete GUI application for interactive transformation editing with 3D visualization.

class TransformEditor(QMainWindow):
    def __init__(self, transform_manager, base_frame, xlim=(-1.0, 1.0), ylim=(-1.0, 1.0), zlim=(-1.0, 1.0), s=1.0, figsize=(10, 10), dpi=100, window_size=(500, 600), parent=None):
        """
        Interactive GUI for editing transformations with 3D visualization.
        
        Parameters:
        - transform_manager: TransformManager - Transform manager instance
        - base_frame: str - Base reference frame name
        - xlim: tuple - X-axis visualization limits
        - ylim: tuple - Y-axis visualization limits  
        - zlim: tuple - Z-axis visualization limits
        - s: float - Frame visualization scaling
        - figsize: tuple - Matplotlib figure size
        - dpi: int - Figure DPI
        - window_size: tuple - GUI window size (width, height)
        - parent: QWidget, optional - Parent widget
        """

    def show(self):
        """Start the GUI application and display editor window."""

    # Attributes after completion:
    # transform_manager: TransformManager - Updated with all edited transformations

PositionEulerEditor Class

Frame editor widget using Euler angle representation for orientation control.

class PositionEulerEditor(QWidget):
    # Signal emitted when frame changes
    frameChanged = QtCore.pyqtSignal()
    
    def __init__(self, base_frame, xlim, ylim, zlim, parent=None):
        """
        Frame editor using position and Euler angles.
        
        Parameters:
        - base_frame: str - Base frame name
        - xlim: tuple - X-axis limits for visualization
        - ylim: tuple - Y-axis limits for visualization
        - zlim: tuple - Z-axis limits for visualization
        - parent: QWidget, optional - Parent widget
        """

    def set_frame(self, A2B):
        """
        Set pose of frame using transformation matrix.
        
        Parameters:
        - A2B: array, shape (4, 4) - Transformation matrix
        """

GUI Availability

Constants indicating PyQt availability and version information.

qt_available: bool  # Whether PyQt is available for GUI functionality
qt_version: int | None  # PyQt version (4 or 5) if available, None otherwise

Usage Examples

Basic Transform Editor

from pytransform3d.editor import TransformEditor, qt_available
from pytransform3d.transform_manager import TransformManager
import pytransform3d.transformations as pt

if qt_available:
    # Create transform manager with some initial transformations
    tm = TransformManager()
    tm.add_transform("base", "link1", pt.transform_from(p=[1, 0, 0]))
    tm.add_transform("link1", "link2", pt.transform_from(p=[0, 1, 0]))
    tm.add_transform("link2", "end_effector", pt.transform_from(p=[0, 0, 0.5]))

    # Create and show editor
    app = QApplication.instance()
    if app is None:
        app = QApplication([])
    
    editor = TransformEditor(tm, "base", xlim=(-2, 2), ylim=(-2, 2), zlim=(-1, 2))
    editor.show()
    
    # Run application
    app.exec_()
    
    # Access modified transformations
    print("Final transformations:")
    for from_frame, to_frame in [("base", "link1"), ("link1", "link2"), ("link2", "end_effector")]:
        T = tm.get_transform(from_frame, to_frame)
        print(f"{from_frame} -> {to_frame}:")
        print(f"  Position: {T[:3, 3]}")
        
else:
    print("PyQt not available - GUI editor cannot be used")

Robot Joint Editor

from pytransform3d.editor import TransformEditor, qt_available
from pytransform3d.transform_manager import TransformManager
import pytransform3d.transformations as pt
import pytransform3d.rotations as pr
import numpy as np

if qt_available:
    # Create robot arm
    tm = TransformManager()
    
    # Base
    tm.add_transform("world", "base", pt.transform_from(p=[0, 0, 0.1]))
    
    # Shoulder joint
    tm.add_transform("base", "shoulder", pt.transform_from(p=[0, 0, 0.2]))
    
    # Upper arm
    tm.add_transform("shoulder", "upper_arm", pt.transform_from(p=[0.3, 0, 0]))
    
    # Elbow joint
    R_elbow = pr.matrix_from_euler([0, -np.pi/4, 0], "xyz", extrinsic=True)
    tm.add_transform("upper_arm", "elbow", pt.transform_from(R=R_elbow))
    
    # Forearm
    tm.add_transform("elbow", "forearm", pt.transform_from(p=[0.25, 0, 0]))
    
    # Wrist
    tm.add_transform("forearm", "wrist", pt.transform_from(p=[0.1, 0, 0]))
    
    # Hand
    tm.add_transform("wrist", "hand", pt.transform_from(p=[0.05, 0, 0]))

    # Launch editor
    app = QApplication.instance()
    if app is None:
        app = QApplication([])
    
    # Configure editor for robot workspace
    editor = TransformEditor(
        transform_manager=tm,
        base_frame="world",
        xlim=(-0.8, 0.8),
        ylim=(-0.8, 0.8), 
        zlim=(0, 1.0),
        s=0.1,  # Smaller frame visualization
        figsize=(12, 8),
        window_size=(800, 600)
    )
    
    editor.show()
    app.exec_()
    
    # Print final robot configuration
    print("\nFinal robot configuration:")
    print(f"Hand position: {tm.get_transform('world', 'hand')[:3, 3]}")
    
else:
    print("PyQt not available - install PyQt5 or PyQt6 to use GUI editor")

Custom Frame Editor

from pytransform3d.editor import PositionEulerEditor, qt_available
import pytransform3d.transformations as pt
import pytransform3d.rotations as pr
import numpy as np

if qt_available:
    from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
    from PyQt5.QtCore import pyqtSlot
    
    class CustomFrameEditor(QMainWindow):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("Custom Frame Editor")
            
            # Create central widget
            central_widget = QWidget()
            self.setCentralWidget(central_widget)
            layout = QVBoxLayout(central_widget)
            
            # Create frame editor
            self.frame_editor = PositionEulerEditor(
                base_frame="world",
                xlim=(-2, 2),
                ylim=(-2, 2), 
                zlim=(-2, 2)
            )
            
            # Connect signal
            self.frame_editor.frameChanged.connect(self.on_frame_changed)
            
            layout.addWidget(self.frame_editor)
            
            # Set initial frame
            initial_transform = pt.transform_from(p=[1, 0, 0.5])
            self.frame_editor.set_frame(initial_transform)
        
        @pyqtSlot()
        def on_frame_changed(self):
            """Handle frame change event."""
            print("Frame was modified by user!")
            # Access current frame state from editor
            # (Implementation depends on specific editor internals)
    
    # Run custom editor
    app = QApplication.instance()
    if app is None:
        app = QApplication([])
    
    editor = CustomFrameEditor()
    editor.show()
    app.exec_()
    
else:
    print("PyQt not available")

Programmatic Frame Editing

from pytransform3d.editor import PositionEulerEditor, qt_available
import pytransform3d.transformations as pt
import pytransform3d.rotations as pr
import numpy as np

if qt_available:
    from PyQt5.QtWidgets import QApplication
    
    # Create application
    app = QApplication.instance()
    if app is None:
        app = QApplication([])
    
    # Create editor widget
    editor = PositionEulerEditor(
        base_frame="base",
        xlim=(-3, 3),
        ylim=(-3, 3),
        zlim=(-1, 3)
    )
    
    # Set various frame poses programmatically
    poses = [
        pt.transform_from(p=[1, 0, 0]),
        pt.transform_from(p=[0, 1, 0]),
        pt.transform_from(p=[0, 0, 1]),
        pt.transform_from(
            R=pr.matrix_from_euler([0, 0, np.pi/4], "xyz", extrinsic=True),
            p=[1, 1, 0]
        )
    ]
    
    # Demonstrate setting different frames
    for i, pose in enumerate(poses):
        print(f"Setting pose {i+1}: position = {pose[:3, 3]}")
        editor.set_frame(pose)
        
        # Show editor briefly (in real app, user would interact)
        editor.show()
        app.processEvents()  # Process GUI events
        
        # In practice, you would wait for user interaction
        # or use signals/slots to handle frame changes
    
    print("Frame editing demonstration complete")
    
else:
    print("PyQt not available - cannot demonstrate frame editor")

Checking GUI Availability

from pytransform3d.editor import qt_available, qt_version

print(f"PyQt available: {qt_available}")
if qt_available:
    print(f"PyQt version: {qt_version}")
    print("GUI editor functionality is available")
    
    # Import GUI classes safely
    from pytransform3d.editor import TransformEditor, PositionEulerEditor
    print("Successfully imported GUI classes")
    
else:
    print("PyQt not available")
    print("Install PyQt5 or PyQt6 to enable GUI functionality:")
    print("  pip install PyQt5")
    print("  or")
    print("  pip install PyQt6")
    
    # Fallback to non-GUI alternatives
    print("Using matplotlib-based visualization instead...")
    # Use standard matplotlib plotting functions

Features

The interactive editor provides:

  • Real-time 3D visualization of transformation changes
  • Slider controls for position and orientation parameters
  • Euler angle representation for intuitive rotation control
  • Live update of transformation matrix display
  • Multi-frame editing capability within transform manager
  • Coordinate frame visualization with customizable scaling
  • Configurable workspace limits for visualization bounds
  • Integration with transform manager for complex kinematic chains

The editor is particularly useful for:

  • Robot joint configuration and workspace exploration
  • Camera pose adjustment for computer vision applications
  • Sensor calibration and mounting parameter optimization
  • Interactive debugging of transformation chains
  • Educational visualization of 3D transformations
  • Rapid prototyping of spatial relationships

Install with Tessl CLI

npx tessl i tessl/pypi-pytransform3d

docs

batch-operations.md

batch-rotations.md

camera.md

coordinates.md

editor.md

index.md

plot-utils.md

rotations.md

trajectories.md

transform-manager.md

transformations.md

uncertainty.md

urdf.md

visualization.md

tile.json