Machines - sliptonic/FreeCAD GitHub Wiki

Starting with the version 1.2 development cycle, the machine data class and editor were added.

FreeCAD CAM Machine Data Model

Overview

The FreeCAD Machine Data Model (src/Mod/CAM/Machine/models/machine.py) provides a unified configuration system that combines physical machine definitions with post-processor settings. This model serves as the single source of truth for all machine-related configuration, including physical capabilities (axes, spindles) and G-code generation preferences.

Relationship to Postprocessors

Historically, the postprocessors contained a large amount of information which was configuration-oriented. This resulted in extensive code duplication between postprocessors and all the problems that implies.

With the introduction of the machine concept, configuration is moving out of the postprocessor. The post processor scripts should become simpler and highly aligned with various machine controllers available in the market. (.e.g. LinuxCNC, Grbl, Mach3/4, Centroid, Masso, etc). The posts will expose the unique functionality of the machine controllers without the configuration and preference information previously seen.

In short, it should be a rare occurrence to write a new postprocessor. A new postprocessor will likely require more cooperation with the development team.

Conversely, it should become easier to create a new machine and configure the individual preferences necessary to achieve user goals and generate useful gcode.

Architecture

Core Design Principles

  1. Unified Configuration: Physical machine definition and post-processor settings in one model
  2. Type Safety: Uses Python dataclasses with type hints for robust configuration
  3. Serialization: Full JSON persistence for configuration sharing and backup
  4. Extensibility: Modular design supports adding new machine types and capabilities

Dataclass Hierarchy

Machine
├── LinearAxis[] (dict)
├── RotaryAxis[] (dict)  
├── Spindle[] (list)
├── OutputOptions
│   ├── HeaderOptions
│   ├── CommentOptions
│   ├── FormattingOptions
│   ├── PrecisionOptions
│   └── DuplicateOptions
└── ProcessingOptions

Core Components

Machine Class

The main container class that represents a complete CNC machine configuration.

@dataclass
class Machine:
    # Physical Machine Definition
    name: str = "Default Machine"
    manufacturer: str = ""
    description: str = ""
    linear_axes: Dict[str, LinearAxis] = field(default_factory=dict)
    rotary_axes: Dict[str, RotaryAxis] = field(default_factory=dict)
    spindles: List[Spindle] = field(default_factory=list)
    
    # Rotary Axis Configuration
    primary_rotary_axis: Optional[str] = None
    secondary_rotary_axis: Optional[str] = None
    compound_moves: bool = True
    prefer_positive_rotation: bool = True
    
    # Post-Processor Configuration
    output: OutputOptions = field(default_factory=OutputOptions)
    processing: ProcessingOptions = field(default_factory=ProcessingOptions)
    postprocessor_file_name: str = ""
    postprocessor_properties: Dict[str, Any] = field(default_factory=dict)

Physical Machine Components

LinearAxis

Represents a linear axis (X, Y, Z) with physical limits and capabilities:

@dataclass
class LinearAxis:
    name: str
    direction_vector: FreeCAD.Vector
    min_limit: float = 0
    max_limit: float = 1000
    max_velocity: float = 10000
    sequence: int = 0

Key Features:

  • Automatic direction vector normalization
  • Limit validation with warnings
  • Velocity validation
  • Sequence ordering for multi-axis synchronization

RotaryAxis

Represents a rotary axis (A, B, C) for 4/5-axis machines:

@dataclass
class RotaryAxis:
    name: str
    rotation_vector: FreeCAD.Vector
    min_limit: float = -360
    max_limit: float = 360
    max_velocity: float = 36000
    sequence: int = 0
    prefer_positive: bool = True

Key Features:

  • Rotation vector normalization with Z-axis fallback
  • Angle limit validation
  • RPM velocity validation
  • Positive rotation preference for optimal toolpaths

Spindle

Represents a spindle/tool with type-specific capabilities:

@dataclass
class Spindle:
    name: str
    spindle_type: SpindleType = SpindleType.ROTARY
    id: Optional[str] = None
    
    # Power and Performance
    max_power_kw: float = 0
    max_rpm: float = 0
    min_rpm: float = 0
    
    # Tool Change and Coolant
    tool_change: str = "manual"
    coolant_flood: bool = False
    coolant_mist: bool = False
    coolant_delay: float = 0.0
    
    # Timing Control
    spindle_wait: float = 0.0  # Delay after spindle start
    
    # Type-Specific Parameters
    laser_wavelength: Optional[float] = None  # nm
    waterjet_pressure: Optional[float] = None  # bar
    plasma_amperage: Optional[float] = None  # amps

Spindle Types:

  • ROTARY: Traditional router/drill spindles
  • LASER: Laser cutting/engraving systems
  • WATERJET: Waterjet cutting systems
  • PLASMA: Plasma cutting systems

Capabilities System: Each spindle type has auto-generated capabilities:

  • Motion capabilities (rotate, move Z/XY)
  • Power control features
  • Coolant/assist gas requirements
  • Special features (auto-focus, probing)

Post-Processor Configuration

OutputOptions

Controls G-code output formatting and content:

@dataclass
class OutputOptions:
    # Main Options
    units: OutputUnits = OutputUnits.METRIC
    output_tool_length_offset: bool = True
    remote_post: bool = False
    output_header: bool = True
    
    # Nested Configuration
    header: HeaderOptions = field(default_factory=HeaderOptions)
    comments: CommentOptions = field(default_factory=CommentOptions)
    formatting: FormattingOptions = field(default_factory=FormattingOptions)
    precision: PrecisionOptions = field(default_factory=PrecisionOptions)
    duplicates: DuplicateOptions = field(default_factory=DuplicateOptions)

Header Options: Controls G-code header content (date, description, tool list, etc.)

Comment Options: Comment formatting and inclusion policies

Formatting Options: Line numbering, spacing, and output formatting

Precision Options: Numeric precision for axes, feed rates, and spindle speeds

Duplicate Options: Modal output suppression for G/M codes and parameters

ProcessingOptions

Controls path processing and transformation:

@dataclass
class ProcessingOptions:
    early_tool_prep: bool = False
    filter_inefficient_moves: bool = False
    split_arcs: bool = False
    tool_change: bool = True
    translate_rapid_moves: bool = False
    xy_before_z_after_tool_change: bool = False
    return_to: Optional[Tuple[float, float, float]] = None

Processing Features:

  • Tool preparation timing
  • Rapid move optimization
  • Arc splitting for compatibility
  • Tool change control
  • Rapid-to-feed translation
  • Safety move decomposition

Usage Patterns

Creating Machine Configurations

Standard 3-Axis Machine

machine = Machine.create_3axis_config()
machine.name = "My CNC Router"
machine.manufacturer = "Shapeoko"

4-Axis Machine

machine = Machine.create_4axis_A_config(a_limits=(-180, 180))
machine.name = "4-Axis Mill"

5-Axis Machine

machine = Machine.create_AC_table_config()
machine.name = "5-Axis Machining Center"

Custom Machine

machine = Machine("Custom Machine")
machine.add_linear_axis("X", FreeCAD.Vector(1, 0, 0), 0, 1000)
machine.add_linear_axis("Y", FreeCAD.Vector(0, 1, 0), 0, 800)
machine.add_linear_axis("Z", FreeCAD.Vector(0, 0, 1), -100, 100)
machine.add_spindle("Main Spindle", max_rpm=24000, max_power_kw=3.5)

Configuration Persistence

# Save configuration
machine.save("/path/to/machine.fcm")

# Load configuration
machine = Machine.from_file("/path/to/machine.fcm")

Post-Processor Integration

# Create post processor with machine config
processor = PostProcessor(machine)
results = processor.export2(job)

# Access machine properties in post processor
if machine.processing.split_arcs:
    # Process arc splitting
    pass

if machine.spindles[0].spindle_wait > 0:
    # Insert spindle wait delay
    pass

Advanced Features

Machine Type Detection

The model automatically detects machine type based on available axes:

@property
def machine_type(self) -> str:
    """Returns: 'xyz', 'xyza', 'xyzb', 'xyzac', 'xyzbc', or 'custom'"""

Unit Conversion

Built-in unit conversion between metric and imperial:

@property
def unit_format(self) -> str:
    return "mm" if self.configuration_units == "metric" else "in"

@property  
def output_unit_format(self) -> str:
    return "mm" if self.output.units == OutputUnits.METRIC else "in"

Validation

Automatic validation during initialization:

  • Axis limit consistency checks
  • Velocity validation
  • Unit format validation
  • Spindle type-specific defaults

Migration from Legacy Systems

Legacy Post Processor Properties

Command Line Arguments

Legacy command-line arguments are deprecated in favor of machine configuration:

Deprecated:

freecad --postprocessor=grbl --preamble="G18 G55" --modal

New Way:

machine.postprocessor_file_name = "grbl"
machine.postprocessor_properties["preamble"] = "G18 G55"
machine.output.duplicates.commands = False
machine.output.duplicates.parameters = False

Extension Points

Custom Spindle Types

Add new spindle types by extending the SpindleType enum:

class SpindleType(Enum):
    ROTARY = "rotary"
    LASER = "laser"
    WATERJET = "waterjet"
    PLASMA = "plasma"
    ULTRASONIC = "ultrasonic"  # New type

Custom Processing Options

Extend ProcessingOptions for new features:

@dataclass
class ProcessingOptions:
    # ... existing fields ...
    custom_feature: bool = False  # New processing option

Post-Processor Properties

Use postprocessor_properties for machine-specific G-code blocks:

machine.postprocessor_properties = {
    "preamble": "G18 G55",
    "postamble": "M2",
    "pre_tool_change": "G53 Z0",
    "post_operation": "M5",
}

Best Practices

Configuration Organization

  1. Use Descriptive Names: Clear machine names and descriptions
  2. Set Proper Limits: Accurate axis limits prevent crashes
  3. Configure Spindles: Complete spindle specifications enable better G-code
  4. Validate Units: Ensure consistent units throughout configuration

Performance Considerations

  1. Lazy Loading: Machine configurations are loaded on-demand
  2. Caching: Serialized configurations are cached for performance
  3. Validation: Minimal validation overhead during normal operation

Error Handling

  1. Graceful Degradation: Missing fields use sensible defaults
  2. Validation Warnings: Invalid configurations log warnings but continue
  3. Migration Support: Automatic migration from older configuration formats

Integration Points

FreeCAD Integration

  • Job Property: Jobs reference machine configurations by name
  • UI Integration: Machine editor provides full configuration interface
  • Post Processing: Export2 uses machine configuration for G-code generation

Post-Processor System

  • Dynamic Loading: Post processors load machine-specific configurations
  • Property Injection: Machine properties injected into post processor scope
  • Validation: Post processors validate required machine capabilities

File System

  • Configuration Files: .fcm files store machine configurations
  • Search Paths: Multiple configuration directories supported
  • Version Control: Configuration files suitable for version control

Troubleshooting

Common Issues

  1. Missing Spindle: Ensure at least one spindle is configured
  2. Invalid Limits: Check axis limit consistency (min < max)
  3. Unit Mismatch: Verify configuration vs output units

Debug Information

Enable debug logging for troubleshooting:

import Path
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())

Validation Errors

Configuration validation provides detailed error messages:

LinearAxis X: min_limit (100) >= max_limit (50)
Spindle Main: max_rpm (24000) must be >= min_rpm (25000)

Future Development

Planned Enhancements

  1. Multi-Axis Support: Support for 4th, 5th axis machines

API Stability

The machine data model API is considered unstable for:

  • Core dataclass structures
  • Serialization format
  • Basic machine operations

Experimental features include:

  • Advanced processing options
  • Custom spindle types
  • Network configuration features