Code Structure

Detailed breakdown of the Fabrica codebase modules

main.py

Application Entry Point

The script that runs automatically on boot. It initializes all subsystems and manages the main event loop.

Key Responsibilities:

  • Initialize I2C bus and scan for devices (PCA9685)
  • Instantiate ServoController and ButtonHandler
  • Load motion plans from storage
  • Handle Short Press (execute motion) and Long Press (enter config mode)
  • Manage memory (Garbage Collection)
config.py

System Configuration

Centralized configuration file. Modify this file to change hardware settings without touching the core logic.

Hardware Constants

  • I2C_CHANNEL, SDA_PIN, SCL_PIN
  • SERVO_CONTROLLER_ADDR (0x40)
  • PWM_FREQ (50Hz)
  • BUTTON_PINS (GPIO list)

Calibration & Defaults

  • SERVO_MIN_PULSE (0°)
  • SERVO_MAX_PULSE (180°)
  • MOTION_PLANS (Default sequences)
servo_controller.py

Servo Driver

Handles low-level communication with the PCA9685 PWM driver chip via I2C.

ServoController.execute_parallel(channels)

Executes the standard folding motion for a list of channels simultaneously.
Motion: Home (0°) → Flip (180°) → Hold (10°).

_set_pwm(channel, on, off)

Writes raw PWM values to the PCA9685 registers.

initialize_all_servos()

Resets all connected servos to the home position (0°).

motion_plan_executor.py

Motion Logic

Orchestrates complex folding sequences involving multiple steps and parallel movements.

MotionPlanExecutor.execute(button_index)

Retrieves the plan for the pressed button and runs it step-by-step.
After all steps complete, it resets all used servos to 0°.

button.py

Button Handler

Manages button inputs with debouncing and state tracking.

  • Handles debouncing (ignore noise)
  • Detects Long Press (>3s) vs Short Press
  • Blinks LED during Long Press
motion_plan_storage.py

Storage Manager

Handles reading/writing motion_plans.json.

  • Atomic writes (temp file + rename) to prevent corruption
  • Loads default plans if file is missing