Skip to content

A method to continuously target an angle and RuntimeError: can't start a new thread #195

Open
@iwanimsand

Description

@iwanimsand

Hi, I have a car with an ackermann steering which I would like to control with a ps4 controller. I searched for a way to continuously target the angle delivered by the controller. But I can't find a satisfactory solution with the library at the moment. I hope that someone here can put me on the right track.

I found also a related question #175 (comment) asked by natikgadzhi:

On a similar note, let's say I'm using a motor for steering and accepting and queueing remote commands. If I queue a command run_for_degrees and it's not yet started executing, but another command run_for_degrees in different direction comes in, I should be able to go to hat.motorqueue[target_port].pop or delete another command from queue, right?

That's unless that command is currently executing. If it's already in progress, any way to see what command is in progress on each port, and interrupt it if needed?

Here is a little program which should simulate the behavior:

from buildhat import Motor, Hat
import time

h = Hat(debug=True)

motor_a = Motor('A')

start_time = time.time()

motor_a.run_to_position(degrees=0, speed=20, blocking=True, direction="shortest")

sleep_time_seconds = 0.05

angles_from_controller = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -20, -40, -40, -39, -40, -35, -38, -35, -30, 0, 20, 40, 35, 35,
                          35, 35, 35, 35, 35, 35, 30, 0, 0, 0]

try:
    while True:
        for angle in angles_from_controller:
            motor_a.run_to_position(degrees=angle, speed=50, blocking=False, direction="shortest")
            time.sleep(sleep_time_seconds)

except RuntimeError as e:
    duration = time.time() - start_time
    print(f"-> Duration: {duration}")
    print(e)

Depending on how the sleep time was chosen, the sooner no more threads can be started.

I know that pybricks has a method https://docs.pybricks.com/en/stable/pupdevices/motor.html#pybricks.pupdevices.Motor.track_target or https://docs.pybricks.com/en/stable/pupdevices/motor.html#pybricks.pupdevices.Motor.run_target which does exactly what I would need.

Questions:

  1. Is there already a way in the library to continuously target an angle of a motor as fast as possible for the given use case and I don't see it actually?
  2. What would be the best way to realize this use case with the functions implemented by the library at the moment?
  3. @chrisruk if there is a concept or existing idea how to implement something like a track_target method for motors in the library, maybe I could try to implement a draft of it - but I would have to know a little more first so that the whole thing would fit into the existing concepts and future development. Maybe there are also changes in a future firmware that would help with it.
    • A quick idea was to add a method in the library that doesn't start a thread and just sends the command to the build HAT. Because I don't expect any feedback, this would be enough. But I haven't checked this idea further and if this fits with the existing concepts at all.

Currently I'm trying to implement my project directly with the serial protocol of the Build HAT without using the Python library - but of course it would be great to be able to use the library.

Thank you for inputs and ideas

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions