Skip to content

Commit

Permalink
add simulavr container for debugging (#12)
Browse files Browse the repository at this point in the history
* script: restructure build commands

* klipper: add simulavr target

* simulavr: add klipper config for simulavr; add compose file for simulavr

* simulavr: set dependencies for klipper service

* move ustreamer to override file; rearrange init service in main compose file; move config for simulavr to printer.cfg

* move printer.cfg for simulavr to extra file

* README: add debugging section

* update docs
  • Loading branch information
mkuf committed Mar 9, 2022
1 parent 67e4855 commit 555b71d
Show file tree
Hide file tree
Showing 8 changed files with 368 additions and 55 deletions.
48 changes: 33 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,17 @@ Follow the official Guides on how to get them up and running.
* https://docs.docker.com/compose/cli-command/#installing-compose-v2


### Add your Configuration to docker-compose.yaml
### Add your Configuration to docker-compose.override.yaml

Locate the ``klipper`` Service within ``docker-compose.yaml`` and update the ``device`` Section with the Serial Port of your Printer.
In this example, the Printer is using device ``/dev/ttymxc3``. Do not edit any other lines.
Locate the ``klipper`` Service within ``docker-compose.override.yaml`` and update the ``device`` Section with the Serial Port of your Printer.
In this example, the Printer is using device ``/dev/ttymxc3``.
```yaml
klipper:
<<: *klipper-svc
volumes:
- ./config:/opt/cfg
- run:/opt/run
- gcode:/opt/gcode
devices:
- /dev/ttymxc3:/dev/ttymxc3
profiles:
- fluidd
- mainsail
```
Locate the ``ustreamer`` Service within ``docker-compose.yaml`` and update the ``device`` Section with the Device Name of your Webcam.
Locate the ``ustreamer`` Service within ``docker-compose.override.yaml`` and update the ``device`` Section with the Device Name of your Webcam.
In this example, the Webcam is using device ``/dev/video0``. Do not edit any other lines.
```yaml
ustreamer:
Expand Down Expand Up @@ -111,7 +103,7 @@ docker compose --profile <profile> up -d
### Change Execution Options
The Entrypoint for all Docker Images within this Repo are the actual Applications, which are run at container execution time.
This makes it possible to set command line Arguments for the Apps as Docker Command.
Within docker-compose.yaml commands are already set, you may update them to fit your needs.
Within docker-compose.yaml commands are already set, you may override them within `docker-compose.override.yaml` to fit your needs.
Example from service Klipper:
```yaml
command:
Expand All @@ -124,7 +116,7 @@ Example from service Klipper:
### Multiple Webcams
The Ustreamer Service is already templated to be easily reused for multi-webcam Setups.
To add a new Ustreamer Service, simply add the following snippet to ``docker-compose.yaml``.
To add a new Ustreamer Service, simply add the following snippet to ``docker-compose.override.yaml``.
Notice, that all service names, container names and traefik labels need to be unique.
Hence replace webcam2 with webcam3 and so on for every webcam you add and update the physical device that gets passed to the container.
```yaml
Expand All @@ -142,7 +134,7 @@ Hence replace webcam2 with webcam3 and so on for every webcam you add and update
### Building Docker images locally
If you'd like to customize the provided Docker Images, you may edit the Dockerfiles within the ``docker/<service>`` Directory.
Images are build in multiple stages, the final stage is called ``run``. Based on this, you can update Service definitions within ``docker-compose.yaml`` to build Images locally.
Images are build in multiple stages, the final stage is called ``run``. Based on this, you can update Service definitions within ``docker-compose.override.yaml`` to build Images locally.
Example: Build Moonraker
Update the ``image:`` name and add a ``build`` config:
Expand Down Expand Up @@ -192,3 +184,29 @@ In case Moonraker is not situated on the same Host as Mainsail, you'll have to e
volumes:
- ./config/mainsail.json:/usr/share/nginx/html/config.json
```
### Debugging the Stack
Debugging the Stack without printer hardware is challenging, as klipper requires a mcu to operate.
For this purpose, you can build a service that emulates a mcu with simulavr, as suggested by the [Klipper Docs](https://github.com/Klipper3d/klipper/blob/master/docs/Debugging.md).
The simulavr Image is part of the Dockerfile for Klipper but is not pushed to any registry, so it needs to be built when needed.
Locate the `docker-compose.simulavr.yaml` in the repository and set the `VERSION` Build-Arg to any Git Reference from [Klipper3d/klipper](https://github.com/Klipper3d) that you would like the mcu code to be compatible with.

This example builds the mcu code from [Klipper3d/klipper:d75154d](d75154d695efb1338cbfff061d226c4f384d127b)
```yaml
build:
context: docker/klipper
target: build-simulavr
args:
VERSION: d75154d695efb1338cbfff061d226c4f384d127b
```

Then start the Stack
```
docker compose \
--profile mainsail \
-f docker-compose.yaml \
-f docker-compose.simulavr.yaml \
up -d
```
157 changes: 157 additions & 0 deletions config/printer-simulavr.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# This file contains example pin mappings for testing with the
# "simulavr" program. To use this config, compile the firmware for an
# AVR atmega644p, enable "low-level configuration options", and enable
# "simulavr software emulation". Further details are in
# docs/Debugging.md.

# See docs/Config_Reference.md for a description of parameters.

[stepper_x]
# Pins: PA5, PA4, PA1
step_pin: PA5
dir_pin: PA4
enable_pin: PA1
microsteps: 16
rotation_distance: 40
endstop_pin: ^PB0
position_min: -0.25
position_endstop: 0
position_max: 200

[stepper_y]
# Pins: PA3, PA2
step_pin: PA3
dir_pin: PA2
enable_pin: PA1
microsteps: 16
rotation_distance: 40
endstop_pin: ^PB1
position_min: -0.25
position_endstop: 0
position_max: 200

[stepper_z]
# Pins: PC7, PC6
step_pin: PC7
dir_pin: PC6
enable_pin: PA1
microsteps: 16
rotation_distance: 8
endstop_pin: ^PB2
position_min: 0.1
position_endstop: 0.5
position_max: 200

[extruder]
# Pins: PC3, PC2
step_pin: PC3
dir_pin: PC2
enable_pin: PA1
microsteps: 16
rotation_distance: 33.500
nozzle_diameter: 0.500
filament_diameter: 3.500
heater_pin: PB4
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PA7
control: pid
pid_Kp: 22.2
pid_Ki: 1.08
pid_Kd: 114
min_temp: 0
min_extrude_temp: 0
max_temp: 210

[heater_bed]
heater_pin: PB3
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PA0
control: watermark
min_temp: 0
max_temp: 110

[fan]
pin: PD6

[mcu]
serial: /opt/run/simulavr.tty

[printer]
kinematics: cartesian
max_velocity: 500
max_accel: 3000
max_z_velocity: 25
max_z_accel: 30


## vvv Required by Moonraker/Mainsail/Fluidd vvv
[virtual_sdcard]
path: /opt/gcode

[display_status]

[pause_resume]

[gcode_macro PAUSE]
description: Pause the actual running print
rename_existing: PAUSE_BASE
# change this if you need more or less extrusion
variable_extrude: 1.0
gcode:
##### read E from pause macro #####
{% set E = printer["gcode_macro PAUSE"].extrude|float %}
##### set park positon for x and y #####
# default is your max posion from your printer.cfg
{% set x_park = printer.toolhead.axis_maximum.x|float - 5.0 %}
{% set y_park = printer.toolhead.axis_maximum.y|float - 5.0 %}
##### calculate save lift position #####
{% set max_z = printer.toolhead.axis_maximum.z|float %}
{% set act_z = printer.toolhead.position.z|float %}
{% if act_z < (max_z - 2.0) %}
{% set z_safe = 2.0 %}
{% else %}
{% set z_safe = max_z - act_z %}
{% endif %}
##### end of definitions #####
PAUSE_BASE
G91
{% if printer.extruder.can_extrude|lower == 'true' %}
G1 E-{E} F2100
{% else %}
{action_respond_info("Extruder not hot enough")}
{% endif %}
{% if "xyz" in printer.toolhead.homed_axes %}
G1 Z{z_safe} F900
G90
G1 X{x_park} Y{y_park} F6000
{% else %}
{action_respond_info("Printer not homed")}
{% endif %}

[gcode_macro RESUME]
description: Resume the actual running print
rename_existing: RESUME_BASE
gcode:
##### read E from pause macro #####
{% set E = printer["gcode_macro PAUSE"].extrude|float %}
#### get VELOCITY parameter if specified ####
{% if 'VELOCITY' in params|upper %}
{% set get_params = ('VELOCITY=' + params.VELOCITY) %}
{%else %}
{% set get_params = "" %}
{% endif %}
##### end of definitions #####
{% if printer.extruder.can_extrude|lower == 'true' %}
G91
G1 E{E} F2100
{% else %}
{action_respond_info("Extruder not hot enough")}
{% endif %}
RESUME_BASE {get_params}

[gcode_macro CANCEL_PRINT]
description: Cancel the actual running print
rename_existing: CANCEL_PRINT_BASE
gcode:
TURN_OFF_HEATERS
CANCEL_PRINT_BASE
29 changes: 29 additions & 0 deletions docker-compose.override.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## Ustreamer base Service
x-ustreamer-svc: &ustreamer-svc
image: mkuf/ustreamer:nightly
restart: unless-stopped
command:
- "--host=0.0.0.0"
- "--port=8080"
- "--slowdown"
- "--device=/dev/webcam"
- "--resolution=1280x960"
- "--format=MJPEG"
- "--desired-fps=30"

## Add your personal config here
services:
klipper:
devices:
- /dev/ttymxc3:/dev/ttymxc3

ustreamer:
<<: *ustreamer-svc
container_name: ustreamer
devices:
- /dev/video0:/dev/webcam
labels:
- "traefik.enable=true"
- "traefik.http.services.ustreamer.loadbalancer.server.port=8080"
- "traefik.http.routers.ustreamer.rule=PathPrefix(`/stream`)"
- "traefik.http.routers.ustreamer.entrypoints=web"
37 changes: 37 additions & 0 deletions docker-compose.simulavr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
services:
## simulavr
simulavr:
image: simulavr
container_name: simulavr
build:
context: docker/klipper
target: build-simulavr
args:
VERSION: master
privileged: true
volumes:
- /dev:/dev
- run:/opt/run

## Reconfigure Klipper service for simulavr
klipper:
depends_on:
init:
condition: service_completed_successfully
simulavr:
condition: service_started
privileged: true
volumes:
- ./config:/opt/cfg
- run:/opt/run
- gcode:/opt/gcode
- log:/opt/log
- /dev:/dev
command:
- "-I"
- "run/klipper.tty"
- "-a"
- "run/klipper.sock"
- "cfg/printer-simulavr.cfg"
- "-l"
- "log/klippy.log"
42 changes: 8 additions & 34 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,9 @@ x-klipper-svc: &klipper-svc
- "-l"
- "log/klippy.log"

x-ustreamer-svc: &ustreamer-svc
image: mkuf/ustreamer:nightly
restart: unless-stopped
command:
- "--host=0.0.0.0"
- "--port=8080"
- "--slowdown"
- "--device=/dev/webcam"
- "--resolution=1280x960"
- "--format=MJPEG"
- "--desired-fps=30"

## Service Definitions
services:

## Config dir needs to be writable by uid/gid 1000
## This container sets the right permissions and exits
init:
image: busybox:latest
container_name: init
command: chown -R 1000:1000 /prind/config
volumes:
- .:/prind

## Klippy Services
##
klipper:
Expand All @@ -50,8 +29,6 @@ services:
- run:/opt/run
- gcode:/opt/gcode
- log:/opt/log
devices:
- /dev/ttymxc3:/dev/ttymxc3
profiles:
- fluidd
- mainsail
Expand Down Expand Up @@ -150,17 +127,14 @@ services:
## Accompanying Services/Infra
##

## Webcam Service
ustreamer:
<<: *ustreamer-svc
container_name: ustreamer
devices:
- /dev/video0:/dev/webcam
labels:
- "traefik.enable=true"
- "traefik.http.services.ustreamer.loadbalancer.server.port=8080"
- "traefik.http.routers.ustreamer.rule=PathPrefix(`/stream`)"
- "traefik.http.routers.ustreamer.entrypoints=web"
## Config dir needs to be writable by uid/gid 1000
## This container sets the right permissions and exits
init:
image: busybox:latest
container_name: init
command: chown -R 1000:1000 /prind/config
volumes:
- .:/prind

## Loadbalancer/Proxy
traefik:
Expand Down
Loading

0 comments on commit 555b71d

Please sign in to comment.