Path Planning - foolofato0k/Robo-Studio2 GitHub Wiki

Summary

Summary and Scope

This subsystem handles following the optimal path between all the points, ensuring the outlined images is rescaled to fit a larger piece of paper ending a one-to-one recreation of the outputted image.

Scope:

  • Scale input data to a specified size (A4 default)
  • Implement a Travelling Salesperson optimisation to decrease drawing time
  • Generate a drawing path that the UR3 can successfully follow
Architecture

Architecture

PoseSequenceBuilder()

PoseSequenceBuilder()

The main functionality is in the class PoseSequenceBuilder() in the file pose_sequence_builder.py

The class consists of 3 static functions:

All functions have input: List[List[Tuple[float,float]]]

To use the class call the functions in the following order:

  1. scale_and_center() (optional)
  2. optimise_path() (optional)
  3. build_pose_array()
scale_and_center()

scale_and_center()

Purpose:

Scales stroke plan to designated size and center. This should be used after image processing.

Parameters:

  • strokes: The current stroke plan. This should be the output from image processing.

  • target_width: The scaling width (mm) with default of 0.297.

  • target_height: The scaling height (mm) with default of 0.210.

  • center: The target center of drawing path in the UR3 frame of reference with a default of (0.0, 0.0).

  • margin: Creates a margin around the scaled dimensions, defaulting to 0.02.

optimise_path()

optimise_path()

Purpose

Reorders the strokes and optionally reverses them to minimize total travel distance using a Travelling Salesperson Problem (TSP) approach. This is used to reduce drawing time by minimizing unnecessary arm motion.

Parameters:

strokes: List of original strokes with each stroke as a list of (x, y) tuples.

Returns:

Optimized list of strokes in the new order

build_pose_array()

build_pose_array()

Purpose:

Generates a full PoseArray for the UR3, consisting of lifted poses before and after each stroke and drawing poses in between. A central "start" pose is also included to guide the robot into position.

Parameters

scaled_strokes: List of scaled and centered strokes (as Pose objects).

lift_height: Z-height (m) used for moving above the drawing surface.

draw_height: Z-height (m) used during drawing strokes.

Returns

PoseArray – Complete sequence of poses for drawing the image.

Tests

Tests

Path Plan and Scaling

Path Plan and Scaling Test

From the root of the git repositiory run:

python3 src/py_planning/test/planning_tests.py

This contains 2 Tests:

The first test validates the correct conversion of stroke poses into a suitable pose array. This test ensures your robot’s trajectory logic follows a safe and correct up → down → draw → up sequence, minimizing unnecessary contact with the drawing surface.

It tests the following:

  • Z - lift height
  • Z - draw height
  • Correct number of drawing points
  • A lifted start and lifted end of entire sequence

The second test validates that strokes are scaled and centered properly within a target canvas (e.g., A4 page), without exceeding its bounds.

It tests the following:

  • X and Y values fall within ±target_width / 2
  • X and Y values fall within ±target_height / 2

This test ensures your drawing will fit inside the physical paper space, remain centered, and not be clipped or distorted when sent to the robot for execution.

LKH-3

LKH-3 Test

Tests and visualizes the performance of the stroke ordering optimizer — specifically the solve_stroke_order_py() function from the py_planning.lkh_utils module using synthetic stroke data.

From the github repository root run:

python3 src/py_planning/py_planning/test_tsp.py

The first image demonstrates a sequence of strokes that is unoptimised. The coloured lines indicate the strokes, and the dashed lines indicate the path between stokes. Unsolved TSP

The second image is the solved stroke sequence. Solved TSP

Optimisation

Optimisation Test

To test optimisation run

ros2 run py_planning processing_node

This will process and display the results for a default image. The test is validated through visual inspection, which should reveal that the optimised path is much smoother and will be more efficient.

Default image

Default Image

Before Optimisation

image

After Optimisation

Optimised Image

⚠️ **GitHub.com Fallback** ⚠️