adding matrices and usb devices for use cases/3 DoF Arms

Okay. What is a good example of writing usb devices in matrices via Python3 and/or C/C++?

The logic or connections made on this effort are for me so far, i.e. no commercial product or for groups in the public eye.

So far, I have attained the access to handle /dev/ttyACM0 without calling it. It works on the BeagleY-AI with the port opened by beagleboard.org.

Still…

I cannot associate my matrices with the /dev/ttyACM0 device thus far. I think putting this file, main.cpp, in some circumstances with /dev/ttyACM0 will be beneficial to the build. Now, can I do it alone? I do not know…

Things in this file look like this so far:

#!/usr/bin/python3

import sys
import usb.core
import usb.util
from protocol import *
import numpy as np


# Constant definitions mimicking the C++ implementation
VENDOR_ID = 0x1FFB
PRODUCT_IDS = [0x0089, 0x008A, 0x008B, 0x008C]
REQUEST_SET_TARGET = 0x85  # The standard Pololu Maestro native USB request ID


def find_maestro_device():
    """Loops through known product IDs to find the Pololu Maestro device."""
    for pid in PRODUCT_IDS:
        device = usb.core.find(idVendor=VENDOR_ID, idProduct=pid)
        if device is not None:
            return device
    return None


def set_target(device, position, servo=0):
    """Sends the target position to a specific servo channel using a control transfer."""
    # bmRequestType = 0x40 (Vendor-defined request, host-to-device direction)
    bm_request_type = 0x40
    b_request = REQUEST_SET_TARGET

    # Value parameter requires position in quarter-microseconds (input * 4)
    w_value = int(position * 4)
    w_index = int(servo)

    try:
        # usb.core.Device.ctrl_transfer(bmRequestType, bRequest, wValue, wIndex, data_or_wLength, timeout)
        device.ctrl_transfer(
            bm_request_type, b_request, w_value, w_index, data_or_wLength=0, timeout=5000
        )
    except usb.core.USBError as e:
        print(f"USB Transfer failed: {e}", file=sys.stderr)

def create_3dof_matrix(x, y, theta_rad):
    """
    Creates a 3 DoF homogeneous transformation matrix (3x3).

    Parameters:
    x, y      : Translation along X and Y axes
    theta_rad : Rotation angle in radians
    """
    cos_t = np.cos(theta_rad)
    sin_t = np.sin(theta_rad)

    # Define the 3x3 transformation matrix
    matrix = np.array([
        [cos_t, -sin_t, x],
        [sin_t,  cos_t, y],
        [0,      0,     1]
    ])

    return matrix

# 1. Define transformation parameters (Move 5 units X, 2 units Y, Rotate 45 degrees)
angle = np.radians(45)
T_a_to_b = create_3dof_matrix(5.0, 2.0, angle)

print("Transformation Matrix (Frame A to B):")
print(T_a_to_b)

# 2. Define a point in Frame B: [X, Y, 1] for homogeneous coordinates
point_in_b = np.array([1.0, 0.0, 1.0])

# 3. Transform the point to Frame A using matrix multiplication
point_in_a = np.dot(T_a_to_b, point_in_b)

print("\nTransformed Point in Frame A:")
print(point_in_a[:2]) # Extract just the X and Y coordinates


def main():
    print("Searching for Pololu Maestro device...")
    device = find_maestro_device()

    if device is None:
        print("Error: Maestro device not found. Check physical connections or permissions.")
        sys.exit(1)

    print("Device found and initialized successfully.")
    servo_channel = 0

    try:
        while True:
            user_input = input("Enter position (or 'q' to quit): ").strip()
            if user_input.lower() == "q":
                break

            try:
                position = int(user_input)
                set_target(device, matrix=position, servo_channel)
            except ValueError:
                print("Invalid input. Please enter an integer number.")

    except KeyboardInterrupt:
        print("\nExiting program.")
    finally:
        # PyUSB handles closing the device and recycling handles implicitly on exit,
        # but clearing configurations ensures safe detachment.
        usb.util.dispose_resources(device)


if __name__ == "__main__":
    main()

I derived some of the source online at Pololu forums, researching ideas online for matrix employing, and deciphering things myself (as usual).

Does anyone see the error?

set_target(device, matrix=position, servo_channel)

That is the error. It is like my source code went awry when I tried to plant matrix from position.

Anyway, this may be as far as I get for now. If you want to use it, go ahead. Try it!

Seth

P.S. It might just work… Of course, you may need to alter it to suit your needs. I will keep with it until completion. I would like to make a write up of a post about the neatness of ttyACM0. It is really a cool tool for devices for now.

update

5v…yay. I will attempt to find a way to post UART examples once I complete my 5v examples via ttyACM0.

I added another function in between create_3dof_matrix and set_target.

It is another matrix but I cannot just make the jump yet from USB to Matrix usage within this file.

Anyway, this is from pyusb.

So, while I would like all the functionality of libusb.h, I can at least use it to build upon in the future with their way, the makers of pyusb, of distinguishing libraries not associated with their building in Python3.

See here:

>>> import usb.core
>>> import usb.backend.libusb1
>>>
>>> backend = usb.backend.libusb1.get_backend(find_library=lambda x: "/usr/lib/libusb-1.0.so")
>>> dev     = usb.core.find(..., backend=backend)

That is straight from the documentation at pyusb/docs/tutorial.rst at master · pyusb/pyusb · GitHub

It will most likely change. Get it while it is hot! This is exciting to me. If this is boring to you, a-okay. I will build it all myself (hopefully).

I think a book is in order for matrices and Python3. For some reason, I cannot grasp the function needed to handle the logic behind the installment of what works into what does not work.

For instance, set_target(device, position, servo_channel) works and does in fact do what it claims to do but what I have tried in positioning the position has not worked.

So, for even the simplest source code and if statements, my builds in source act too funny.