Robot Aided Drafting
Loading...
Searching...
No Matches
Functions | Variables
ImageToAngles Namespace Reference

Functions

List[Tuple[float, float, int]] parse_png (str|Path path)
 
List[Tuple[float, float, int]] normalize (Sequence[Tuple[float, float, int]] pts)
 
List[Tuple[float, float, int]] downsample_by_dist (Sequence[Tuple[float, float, int]] pts, float min_dist)
 
Tuple[float, float] ik_xy (float x, float y)
 
List[Tuple[float, float]] ik_path (Sequence[Tuple[float, float, int]] pts)
 
None main ()
 

Variables

 L1
 
 L2
 
float OFFSET_T2_DEG = 147.5
 
tuple X_RANGE = (-6, -2)
 
tuple Y_RANGE = (5.5, 9)
 

Detailed Description

@file        ImageToAngles.py
@brief       Convert a black-on-white PNG drawing to SCARA waypoints.

Every foreground (“ink”) pixel in the skeletonized PNG becomes one waypoint,
visited in depth-first order along the pixel-adjacency graph.  The result is:

1. **(x, y, z) path**  
   *z = 1* marks a pen-up jump between disconnected components.

2. **(θ₁, θ₂, z) moves**  
   Inverse-kinematics converts Cartesian waypoints to joint angles, ready to
   stream straight to the robot.

@par Example
@code
python ImageToAngles.py shark.png               # full resolution
python ImageToAngles.py shark.png --px-skip 3   # coarser skip
python ImageToAngles.py shark.png --min-dist 0.1  # ≥0.1 in apart
@endcode

Function Documentation

◆ downsample_by_dist()

List[Tuple[float, float, int]] ImageToAngles.downsample_by_dist ( Sequence[Tuple[float, float, int]] pts,
float min_dist )
@brief  Remove redundant waypoints that are closer than *min_dist*.

@param pts       Input waypoints (inch units).
@param min_dist  Minimum allowable spacing (inches).  
                 Points with *z = 1* (pen-up) are **never** removed.
@return          Filtered list with fewer than or equal to *len(pts)*
                 elements.

Referenced by main().

◆ ik_path()

List[Tuple[float, float]] ImageToAngles.ik_path ( Sequence[Tuple[float, float, int]] pts)
@brief  Vectorized helper: apply :pyfunc:`ik_xy` to an entire path.

@param pts  Waypoints **after** normalization/down-sampling.
@return     List of *(θ₁, θ₂)* pairs in degrees.

References ik_xy().

Referenced by main().

◆ ik_xy()

Tuple[float, float] ImageToAngles.ik_xy ( float x,
float y )
@brief  Two-link planar inverse kinematics.

@param x  X-coordinate in inches.
@param y  Y-coordinate in inches.
@return   (θ₁, θ₂) in **degrees**.  Both angles are made negative so that
          positive robot motion matches the SCARA’s CCW convention.

@throw ValueError  If *(x, y)* lies outside the reachable workspace.

Referenced by ik_path().

◆ main()

None ImageToAngles.main ( void )
@brief  Parse CLI arguments, run full pipeline, and write *image_thetas.txt*.

The output file contains one line per waypoint in the format  
`{θ₁, θ₂, z},` – ready for the robot firmware.

References downsample_by_dist(), ik_path(), main(), normalize(), and parse_png().

Referenced by main().

◆ normalize()

List[Tuple[float, float, int]] ImageToAngles.normalize ( Sequence[Tuple[float, float, int]] pts)
@brief  Scale and center pixel waypoints into the SCARA workspace.

The drawing is **uniformly** scaled to fit inside *X_RANGE × Y_RANGE*
while preserving aspect ratio, and then translated so its centroid lies
at the center of that rectangle.

@param pts  Waypoints from :pyfunc:`parse_png` in pixel units.
@return     Same list of points, but in **inch units** relative to the
            robot base.

Referenced by main().

◆ parse_png()

List[Tuple[float, float, int]] ImageToAngles.parse_png ( str | Path path)
@brief  Skeletonize the PNG and traverse its pixel graph.

@param path  Path to a *black-on-white* PNG image.
@return      Ordered list of **(x, y, z)** waypoints in **pixel units**  
             where *z = 1* designates a pen lift between disconnected
             strokes.

@throw FileNotFoundError   If *path* cannot be opened.

Referenced by main().

Variable Documentation

◆ L1

ImageToAngles.L1

◆ L2

ImageToAngles.L2

◆ OFFSET_T2_DEG

float ImageToAngles.OFFSET_T2_DEG = 147.5

◆ X_RANGE

tuple ImageToAngles.X_RANGE = (-6, -2)

◆ Y_RANGE

tuple ImageToAngles.Y_RANGE = (5.5, 9)