Skip to main content

Multi-font text writer library for the Dobot Magician robotic arm

Project description

๐Ÿค– dobot-writer

A multi-font text-writing library for the Dobot Magician robotic arm.

Write text on paper with your Dobot Magician using a choice of built-in fonts โ€” from clean geometric strokes to flowing cursive, hollow stencil outlines, and heavy bold. All fonts are custom designs created for this project.


โœจ Features

Font Style Description
CLASSIC Single-stroke Clean, geometric โ€” one stroke per segment
CURSIVE Single-stroke Rounded, arc-based, flowing letterforms
ITALIC Single-stroke CLASSIC sheared ~15ยฐ to the right
STENCIL Double-line Two parallel strokes with a hollow gap โ€” stencil/outline look
BOLD Multi-pass Triple overdraw for a heavier, thicker appearance
CURSIVE_ITALIC Single-stroke CURSIVE with additional right-lean shear
STENCIL_CURSIVE Double-line CURSIVE rendered as hollow stencil outlines

You can also combine any transforms to create your own font on the fly:

from dobot_writer.fonts import CLASSIC, make_stencil, make_italic
MY_FONT = make_italic(make_stencil(CLASSIC), slant=0.35)

๐Ÿ“ฆ Installation

From PyPI

pip install dobot-writer

From source (for development / this repo)

git clone https://github.com/armouredalpha/dobot-writer.git
cd dobot-writer
pip install -e ".[dev]"

Requirements: Python โ‰ฅ 3.8 ยท pydobotplus ยท pyserial


๐Ÿš€ Quick Start

Interactive mode (guided setup)

from dobot_writer import DobotWriter, WritingConfig
from dobot_writer.fonts import CURSIVE

cfg = WritingConfig(
    char_height_mm=20,   # letter height in mm
    char_width_mm=14,    # letter width in mm
    write_vel=150,       # mm/s pen-down speed
)

with DobotWriter(config=cfg) as writer:
    writer.setup()                        # โ‘  pick port  โ‘ก teach origin  โ‘ข auto-Z
    writer.write("HELLO WORLD", font=CURSIVE)

Running writer.setup() walks you through three interactive steps:

  1. Port selection โ€” lists available COM/USB ports; you pick one.
  2. Teach mode โ€” jog the arm to the top-left corner of your writing area, press ENTER.
  3. Auto-Z calibration โ€” the arm steps down by z_step_mm until you type stop when the pen just touches the paper.

Non-interactive mode (known coordinates)

If you already know the robot's Cartesian coordinates for your writing area:

from dobot_writer import DobotWriter, WritingConfig
from dobot_writer.fonts import STENCIL

writer = DobotWriter(port="COM3", config=WritingConfig())
writer.connect()
writer.set_origin(x=200.0, y=0.0)   # pen tip start position (mm)
writer.set_z(z_write=-50.0)          # pen-contact Z (mm)

writer.write("DOBOT", font=STENCIL)
writer.close()

๐ŸŽจ All Fonts Demo

from dobot_writer import DobotWriter, WritingConfig
from dobot_writer.fonts import list_fonts, get_font

cfg = WritingConfig(char_height_mm=18, line_spacing_mm=30)

with DobotWriter(config=cfg) as writer:
    writer.setup()
    for i, name in enumerate(list_fonts()):
        writer.write(
            f"{name}",
            font=get_font(name),
            start_x_offset=-(i * cfg.line_spacing_mm),
        )

๐Ÿ› ๏ธ API Reference

DobotWriter

DobotWriter(port=None, config=None, verbose=True)
Method Description
connect() Open serial connection
close() Close serial connection
setup() Interactive port โ†’ teach โ†’ auto-Z calibration
set_origin(x, y) Set writing origin programmatically (mm)
set_z(z_write, lift_mm=None) Set pen-contact Z programmatically (mm)
write(text, font=None, ...) Write text on paper
estimate_width(text) Estimate writing width in mm
get_pose() Return current arm pose
list_ports() Static โ€” list available serial ports

WritingConfig

All fields have sensible defaults. Override only what you need:

WritingConfig(
    char_height_mm  = 20.0,   # letter height (mm)
    char_width_mm   = 14.0,   # letter width  (mm)
    char_gap_mm     = 4.0,    # gap between characters
    word_gap_mm     = 12.0,   # gap for a space character
    line_spacing_mm = 32.0,   # baseline-to-baseline for \n
    lift_mm         = 5.0,    # pen lift height during travel
    z_step_mm       = 0.5,    # auto-Z step size
    write_vel       = 150,    # pen-down speed
    travel_vel      = 500,    # pen-up speed
    stencil_offset  = 0.065,  # half-gap for stencil fonts [0โ€“1]
)

Font Utilities

from dobot_writer.fonts import list_fonts, get_font, supported_chars

list_fonts()              # ['BOLD', 'CLASSIC', 'CURSIVE', ...]
get_font("stencil")       # returns the STENCIL font dict
supported_chars(CLASSIC)  # '!"#%&\'()*+,-./0123456789:;?@ABCDE...'

Transform Factories

from dobot_writer.fonts import make_italic, make_stencil, make_bold, make_mirror

make_italic(font, slant=0.28)    # right-lean shear (~15ยฐ)
make_stencil(font, offset=0.065) # double-outline / hollow
make_bold(font, spread=0.04)     # triple-pass thickening
make_mirror(font)                # horizontal flip

๐Ÿ”ค Writing Coordinate System

Robot arm base
โ”‚
โ”‚  start_x (X axis, โˆ’X = new lines)
โ”‚  โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
โ”‚  [H]  [E]  [L]  [L]  [O]     โ† each cell is char_width_mm wide
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ start_y (Y axis, writing direction)
โ”‚
โ”‚  Font coords inside each cell:
โ”‚    x: 0.0 (left) โ†’ 1.0 (right)   maps to robot +Y
โ”‚    y: 0.0 (bottom) โ†’ 1.0 (top)   maps to robot +X
  • Text advances in the +Y direction.
  • New lines step in the โˆ’X direction.
  • The pen lifts to z_travel = z_write + lift_mm between strokes.

โœ๏ธ Creating Your Own Font

A font is a plain Python dict[str, list[list[tuple[float, float]]]]:

MY_FONT = {
    'A': [
        [(0.0, 0.0), (0.5, 1.0), (1.0, 0.0)],   # two legs
        [(0.2, 0.4), (0.8, 0.4)],                 # crossbar  โ† separate polyline = pen lift
    ],
    'B': [ ... ],
    ' ': [],   # space โ€” just advance the cursor
}

writer.write("AAB", font=MY_FONT)

Rules:

  • x and y are in [0, 1] (font units). Values just outside [0,1] are fine for descenders/serifs.
  • Each item in the outer list is one polyline (continuous pen stroke). The pen lifts between polylines.
  • The pen always lifts after the last polyline in a glyph.
  • Lowercase chars are automatically looked up as uppercase.

๐Ÿ–ฅ๏ธ Supported Characters (CLASSIC / CURSIVE)

! " # % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9
: ; ? @ A B C D E F G H I J K L M N O P Q R S T
U V W X Y Z [ \ ] _

๐Ÿงช Running Tests

pip install -e ".[dev]"
pytest tests/ -v

๐Ÿ“ Project Structure

dobot-writer/
โ”œโ”€โ”€ dobot_writer/
โ”‚   โ”œโ”€โ”€ __init__.py         โ† public API
โ”‚   โ”œโ”€โ”€ writer.py           โ† DobotWriter class
โ”‚   โ”œโ”€โ”€ config.py           โ† WritingConfig dataclass
โ”‚   โ””โ”€โ”€ fonts/
โ”‚       โ”œโ”€โ”€ __init__.py     โ† font registry, list_fonts(), get_font()
โ”‚       โ”œโ”€โ”€ _classic.py     โ† CLASSIC font data
โ”‚       โ”œโ”€โ”€ _cursive.py     โ† CURSIVE font data + _make_italic helper
โ”‚       โ””โ”€โ”€ _transforms.py  โ† make_stencil, make_italic, make_bold, make_mirror
โ”œโ”€โ”€ examples/
โ”‚   โ”œโ”€โ”€ hello_world.py
โ”‚   โ”œโ”€โ”€ multi_font.py
โ”‚   โ””โ”€โ”€ custom_font.py
โ”œโ”€โ”€ tests/
โ”‚   โ””โ”€โ”€ test_fonts.py
โ”œโ”€โ”€ pyproject.toml
โ”œโ”€โ”€ LICENSE
โ””โ”€โ”€ README.md

๐Ÿค Contributing

Contributions are very welcome! Ideas for contribution:

  • Add new glyphs or improve existing ones (PR to _classic.py or _cursive.py)
  • Add a new base font (e.g. _block.py, _retro.py)
  • Add a new transform (e.g. make_wavy, make_condensed)
  • Improve auto-Z calibration (e.g. force-sensor support)
  • Add a dry-run / preview mode that plots the strokes without the robot

To contribute:

  1. Fork the repo and create a branch: git checkout -b feat/my-font
  2. Make your changes and add tests in tests/
  3. Run pytest tests/ -v and make sure everything passes
  4. Open a Pull Request with a description of what you changed

๐Ÿ“„ License

MIT โ€” see LICENSE.


๐Ÿ™ Acknowledgements

Font Designs: All fonts and transforms in this library are custom designs.

Dependencies: Uses pydobotplus for Dobot Magician serial communication.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dobot_writer-0.1.0.tar.gz (27.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dobot_writer-0.1.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file dobot_writer-0.1.0.tar.gz.

File metadata

  • Download URL: dobot_writer-0.1.0.tar.gz
  • Upload date:
  • Size: 27.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for dobot_writer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2bef397ef2dac1d9bf064ccd12064d10b1bb3e61370f4b854d70a673a1e58d1a
MD5 700aa2e63330b3b619f4914869c7c83c
BLAKE2b-256 ff4deec087fb0fd7b6b2ecb158a1bd9f8b2bfd663913d37c2ce522e3de6d92bd

See more details on using hashes here.

File details

Details for the file dobot_writer-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: dobot_writer-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for dobot_writer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 028bc869b46c57c64d33191a531809b5010d09e8194dab825e957f98afe40675
MD5 d63456dbdd2c9dd9381132be71e4a1ab
BLAKE2b-256 645a45ad2016d0a96b339d3856938563ff2052a83c85008abf9f7a148b849ae6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page