Recommended Posts

3 hours ago, gyenesvi said:

Hmm, not sure how I could do a good comparison. For one, I don't have a lego remote as it is not useful for me, but even if I had, what do I compare it to? What could be a good test application for the comparison? Comparing two solutions for on-ff throttle / steering (lego remote vs gamepad through BrickController) for example would not really make the difference visible I guess. Do you have any other ideas? I believe the real test would be comparing two ways to use a proportional gamepad controller, (directly or via phone) in a setting that has/requires precise control.

I was already thinking of doing a video comparing the different options for RC.  I have the off road buggy set and I've tried the Lego app, Pybricks with a train controller, BrickController with the Technic Hub and with BuWizz.  For me none of these solutions are satisfying.  I'm pretty sure the end result would be doing a PF conversion that I would like best :pir_laugh2:.  Too bad it wouldn't have proportional control.

While the Pybricks solution did have the least amount of lag IIRC, the train controller is not a good solution for driving a model with traditional steering.  At least PF has a return to center controller and a wheel can be attached to the side.

I'll see what I can do for a side by side comparison.  I can rig something up to activate the controllers at the same time and then count the frames in the video to get a fairly accurate measurement of the lag for each solution.  Looks like I've got my work cut out for me :pir-grin:

Share this post


Link to post
Share on other sites
11 minutes ago, BatteryPoweredBricks said:

While the Pybricks solution did have the least amount of lag IIRC, the train controller is not a good solution for driving a model with traditional steering.

The easiest solution for TLG would be to make an "analogue" version of the train controller, something in the lines of MK's 6-way controller. Then it'd just be a matter of Pybricks in the hub interpreting the inputs as needed.
201179060_max.jpg

Share this post


Link to post
Share on other sites
57 minutes ago, BatteryPoweredBricks said:

I can rig something up to activate the controllers at the same time and then count the frames in the video to get a fairly accurate measurement of the lag for each solution.  Looks like I've got my work cut out for me

Well, if you can do such a comparison, it is very welcome. But it is not clear to me which controllers you want to compare exactly? With Pybricks, you can only connect the on-off lego remote, which has push-buttons and it does not even make much sense to link the buttons to a wheel. Then moving your fingers (or any automated mechanism) from one button to the other has more lag than the BT communication I guess, so it is hard to measure the actual lag.

What would be really convincing for me to see at some point is how smoothly a servo horn follows the movement of a steering wheel or a joystick. I was surprised to see how accurate an RC system is compared to what we get with the Control+ app for example.

54 minutes ago, AVCampos said:

The easiest solution for TLG would be to make an "analogue" version of the train controller, something in the lines of MK's 6-way controller. Then it'd just be a matter of Pybricks in the hub interpreting the inputs as needed.

As we kind of concluded earlier in this thread, production of such a physical controller is not even required, since the latest gamepad controllers support BLE, and could connect to the hub. So it seems it really is just a matter of firmware to interpret the signals. That is why I looked into Pybricks source code, to see what is there already. It seems to me that the major part of it would be coding the (publicly available standard HID) communication protocol that such controllers use and exposing it through a python interface like Pybricks has for the lego remote (apart from coding the standard BLE connection, most of which is already there in Pybricks, but needs some cleanup to make it more generic (now it is partly tied to the lego remote) if I understand correctly).

Share this post


Link to post
Share on other sites
23 minutes ago, gyenesvi said:

Well, if you can do such a comparison, it is very welcome. But it is not clear to me which controllers you want to compare exactly? With Pybricks, you can only connect the on-off lego remote, which has push-buttons and it does not even make much sense to link the buttons to a wheel. Then moving your fingers (or any automated mechanism) from one button to the other has more lag than the BT communication I guess, so it is hard to measure the actual lag.

What would be really convincing for me to see at some point is how smoothly a servo horn follows the movement of a steering wheel or a joystick. I was surprised to see how accurate an RC system is compared to what we get with the Control+ app for example.

The only physical controllers I have to compare would be the train controller and a PS4 controller.  The goal would be to compare touch controls on a phone as well.  Side by side comparisons wouldn't be recorded real time but synced up in the edit.  You basically look at the video for when the button is pressed or slider is moved and then count the frames until the motor responds.  You can then calculate the lag time in ms.  I'll see if I can get something done for this Sunday, if I do I'll make a separate thread to discuss since we're getting a bit off topic in this thread.

Maybe I'll try some MK stuff too, but that would be a later followup.  For now I do have BuWizz to compare as well.

Share this post


Link to post
Share on other sites
2 hours ago, AVCampos said:

The easiest solution for TLG would be to make an "analogue" version of the train controller, something in the lines of MK's 6-way controller. Then it'd just be a matter of Pybricks in the hub interpreting the inputs as needed.
...

Hello,

Does anybody know what is inside thie MK 6-chanel Remotge ?

Can the used uC be replaced by another uC suporting Microphyton and therefore also Phybricks ?

An Arduino Nano BLE 33 with the NRF52840 would be such an candidate in my eyes.

 

Jo

Share this post


Link to post
Share on other sites
2 minutes ago, BrickTronic said:

Does anybody know what is inside thie MK 6-chanel Remotge ?

Most likely it's a 2.4 GHz radio with a generic undocumented Chinese protocol.

Share this post


Link to post
Share on other sites

Hi there,

I have trouble coding with Pybricks (v3.2.2 (Pybricks Code v2.1.0) running under Chrome 110.0.5481.177 on MacOS 11.7.4). I can connect to my Control+ hub, but when I press the upload & run button, nothing happens. I then can only disconnect Bluetooth and reconnect to start over. But with the same result. I tried installing new Pybricks firmware onto the hub several times as well as connecting to the Powered UP app to reinstall the LEGO firmware. No change in behavior. Also I reinstalled the Pybricks browser extension several times.

Last year (using the then current Pybricks) I hat no such problems. Any idea, how I could solve this issue?

Thanks for your help!

Pypricks after pressing F5.png

Share this post


Link to post
Share on other sites

Please gather as much information as you can on how to reproduce the problem and collect logs as described in https://github.com/pybricks/support/discussions/270. If none of the tips there (like turning off all other bluetooth devices) don't help work around the problem then find an existing issue at https://github.com/pybricks/support/issues that matches your problem or start a new issue if there isn't a matching one already and share as much information as you can so we can try to understand the problem better.

Share this post


Link to post
Share on other sites
3 hours ago, David Lechner said:

Please gather as much information as you can on how to reproduce the problem and collect logs as described in https://github.com/pybricks/support/discussions/270. If none of the tips there (like turning off all other bluetooth devices) don't help work around the problem then find an existing issue at https://github.com/pybricks/support/issues that matches your problem or start a new issue if there isn't a matching one already and share as much information as you can so we can try to understand the problem better.

Last console-entry: "Downloading 796 bytes"
Only entry in the device-log: "Web Bluetooth Device Chooser initiating Bluetooth discovery session"

I did not find any existing issue matching my experience. Is there any way, I can roll back to last year's Pybricks? That worked fine for me.

Share this post


Link to post
Share on other sites

Logging Bluetooth packets with Wireshark is really the best way to see what is going on.

Pybricks Code is open source. You can build from source and host on your own https server if you want to keep using an older version.

Share this post


Link to post
Share on other sites

Hello! Is it possible to control multiple hubs with one Lego train remote control?

Share this post


Link to post
Share on other sites

Yes, if you have one "master " to connect the remote and then send data to other hubs.

Share this post


Link to post
Share on other sites
On 3/10/2023 at 10:18 PM, Lok24 said:

Yes, if you have one "master " to connect the remote and then send data to other hubs.

if it's not difficult for you, can I have the number of the discussion thread?

Share this post


Link to post
Share on other sites

Hi all, 

I am working in a project that involves controlling 4 hubs; in a coordinated manner. The way that I found to do it is to run one program in one different tab, which allows me to connect to many different hubs. 

Now I am just begining, but I'm afraid that when the moment of making coordinated moves arrives, I will get tricky. So, now, I am considering to make -as stated before- a master hub, and the make hub to hub communication. Nevertheless, the way That I found was to do by broadcasting and I am not sure if that'll work when the coordination implies more than 2 hubs. Any idea?

 

Many thanks (and whish me luck!)

Edited by HectorMB

Share this post


Link to post
Share on other sites

Hi all, I run a YouTube channel that I post projects to. I want to start using PyBricks on Spike Prime, but the license for BlueKitchen btstack is reserved for non-commercial use. Can anyone confirm what btstack is used for in PyBricks and/or if this one module can not be uninstalled/not used? Thanks so much for your time.

Share this post


Link to post
Share on other sites

BTStack is the Bluetooth library so you can't use Pybricks without it. I don't think there would be an issue with making videos about it though. It would only be an issue if you were redistributing the firmware for commercial purposes.

Share this post


Link to post
Share on other sites

I am using the following code on the lego buggy and am having steering trouble:

https://pastebin.com/cTAXX1r0

Basically the wheels are not adjusting properly. This code used to work on a previous version of the pybricks editor and firmware. I'm also fine with installing an older version if that is possible, so that the code can work again.

Share this post


Link to post
Share on other sites
1 hour ago, MAMZe said:

I am using the following code on the lego buggy and am having steering trouble:

https://pastebin.com/cTAXX1r0

Basically the wheels are not adjusting properly. This code used to work on a previous version of the pybricks editor and firmware. I'm also fine with installing an older version if that is possible, so that the code can work again.

My 2 cents...

in line 30 it should have wait=True...  

In the main loop you are always calling track_target when no buttons are pressed which means calling it every 10ms.... 

I think you should detect when you unpress the button and only then call a run_target or track_target to go to zero position. If you use run_target you can define the THEN mode which can be used to stay actively in the 0 position using HOLD. 

So you call it just once, when the button goes from pressed to unpressed.

Hope it helps! 

Share this post


Link to post
Share on other sites

You'll want to delete these lines:

# Read the current settings
#old_kp, old_ki, old_kd, _, _ = steer.control.pid()
 
# Set new values
#steer.control.pid(kp=old_kp*4, kd=old_kd*0.4)

This was a bit of a hack that was needed only in very early version I shared with @kbalage, but it is has now spread all over the internet 😁.

This is now done internally. So if you do it in your script, that makes the kp gain way too high so the motor is all over the place.

Share this post


Link to post
Share on other sites

For some time, I'm having problems when running the programs of 3 Mindstorms hubs simultaneously. In particular, I lose connection or the programs stops by their own frequently. I keep the PC connected to one of them which broadcasts to the others. O have to check the BT version, which I'm afraid can be 4.2.

 

Has someone else experience similar issues? Any ideas?

Share this post


Link to post
Share on other sites

Pybricks! :) 

I have been making some tests today, and indeed, the main problem, rather than connection, is that, somehow, the programs stops randomly (but always when no operation is underway). Often, when there's no input for 1-2 minutes...

 

Edited by HectorMB

Share this post


Link to post
Share on other sites

Also, I noticed that when I try to measure de load of a motor, it gives me an error indicating that there's not such attribute...

 

Any idea?

Edited by HectorMB

Share this post


Link to post
Share on other sites
11 hours ago, Pybricks said:

The best chance to get detailed help is to ask here: https://github.com/pybricks/support/issues Thank you!

In order to be able to help, can you share a small program that reproduces your issue? When the program stops, what is the error message that you see?

Thanks, I will take a look there! :) I'm just a beginner and, not educated into programing languages, and I just learnt by reading here and there ;). 

As you asked, I leave you a picture of the project itself, in case it helps:

Arm.jpg

This is the program I run in the "Master" hub (The one located at the base)

from pybricks.hubs import InventorHub
from pybricks.pupdevices import Motor, ColorSensor, UltrasonicSensor, ColorDistanceSensor
from pybricks.parameters import Button, Color, Direction, Port, Side, Stop
from pybricks.robotics import DriveBase
from pybricks.tools import wait, StopWatch
from pybricks.experimental import Broadcast
from umath import asin, acos, atan, degrees
 
radio = Broadcast(topics=["INPUT"])
 
hub = InventorHub()
BaseA = Motor(Port.A, Direction.COUNTERCLOCKWISE, ([1, 20], [12,60]))
BaseB = Motor(Port.B, Direction.CLOCKWISE, ([1, 20], [12,60]))
BaseC = Motor(Port.C, Direction.CLOCKWISE, ([1, 20], [12,60]))
BaseD = Motor(Port.D, Direction.COUNTERCLOCKWISE, ([1, 20], [12,60]))
Sensor = ColorDistanceSensor(Port.E)
 
radio = Broadcast(topics=["INPUT"])
CalClaw = 0
 
info2=int(0)
info6=int(0)
 
print("Calibrate base? (Yes=LEFT, No=RIGHT)")
pressed = []
while not any(pressed):
    wait (10)
    pressed = hub.buttons.pressed()
if Button.LEFT in pressed:
    calibration = 0
    BaseA.run(10)
    BaseB.run(10)
    BaseC.run(10)
    BaseD.run(10)
    dist=0
    while calibration < 1:
        dist= Sensor.distance()
        print(dist)
        if dist < 50 :
            wait(200)
            BaseA.brake()
            BaseB.brake()
            BaseC.brake()
            BaseD.brake()
            wait(1000)
            BaseA.run_angle(10, -72, Stop.HOLD, wait=False)
            BaseB.run_angle(10, -72, Stop.HOLD, wait=False)
            BaseC.run_angle(10, -72, Stop.HOLD, wait=False)
            BaseD.run_angle(10, -72)
            BaseA.reset_angle(0)
            BaseB.reset_angle(0)
            BaseC.reset_angle(0)
            BaseD.reset_angle(0)
            wait(1000)
            calibration =1
            hub.light.blink(Color.GREEN, [500, 500])
            wait(3000)
 
if Button.RIGHT in pressed or calibration == 1:
    info1=int(0)
    while CalClaw == 0:
        print("Close Claw (0 to 5000, Close: Neg, Open: Pos):")
        Adjust=int(input())
        info2=int(0)
        info3=int(0)
        info4=int(0)
        info5=int(0)
        info = Adjust, info2, info3, info4, info5
        radio.send("INPUT", info)
        if Adjust == 0:
            CalClaw = 1
            print("Claw Calibrated (and closed)")
    while True:
        print("Distance in coordinates, X:")
        X=int(input())
        print("Y:")
        Y=int(input())
        print("Z:")
        Z=int(input())
       
        if X == 999:
            print("Claw (5000= Open; 0= Close):")
            info1 = int(input())
            print("Wrist Torsion (Pos=Clockwise; Neg=Counterwise):")
            info2 = int(input())
            print("Wrist Vertical (Pos= Up; Neg=Down):")
            info3 = int(input())
            print("Elbow (Pos=Up; Neg= Down):")
            info4 = int(input())
            print("Shoulder Vertical(Pos= Forwards; Neg= Backward):")
            info5=int(input())
            print("Shoulder rotation(Pos=Right; Neg= Left):")
            info6=int(input())
            info = info1, info2, info3, info4, info5
            radio.send("INPUT", info)
            wait(100)
        if 0 < X < 999:
            A = 24.6
            B = 20.3
            f1=3.9
            f2=8.6
           
            Dist=pow(pow(X,2)+pow(Y,2),0.5)
            info6=degrees(atan(Y/X))
            H=pow(pow(Dist,2)+pow((f2+Z),2),0.5)
            h1 = (pow(A,2)-pow(B,2)-pow(H,2))/(-2*H)
            h2=H-h1
            C=pow(pow(A,2)-pow(h2,2), 0.5)
 
            a=degrees(asin(C/A))
            a1=degrees(acos(Dist/H))
            info5=(90-(a+a1))*0.7
 
            g=degrees(asin(C/B))
            g1=degrees(asin(Dist/H))
            info3=180-(g+g1)
 
            b=180-(a+g)
            info4=(b-90)*0.80
           
           
           
 
            info = info1, info2, info3, info4, info5
 
        print("Claw:", info1)
        print("Wrist Torsion:", info2)
        print("Wrist Vertical:", info3)
        print("Elbow:", info4)
        print("Shoulder Vertical:", info5)
        print("Shoulder Rotation:", info6)
        wait(100)
        radio.send("INPUT", info)
        #if info :
        RInfo6 = info6*0.835
        BaseA.run_target(20, RInfo6, wait=False)
        BaseB.run_target(20, RInfo6, wait=False)
        BaseC.run_target(20, RInfo6, wait=False)
        BaseD.run_target(20, RInfo6)
        if X == 0 and Y == 0:
            print("Claw (5000= Open; 0= Close):")
            info1 = int(input())
            info = info1, info2, info3, info4, info5
            radio.send("INPUT", info)
            wait(100)
            print(info)
            wait(100)
 
       

 

 

This is the one that gives me more problems (see below), which is the one on top, and that controls the claw, the wrist rotation and the wrist vertical movement. 

from pybricks.hubs import InventorHub
from pybricks.pupdevices import Motor, ColorSensor, ColorDistanceSensor, UltrasonicSensor
from pybricks.parameters import Button, Color, Direction, Port, Side, Stop
from pybricks.robotics import DriveBase
from pybricks.tools import wait, StopWatch
from pybricks.experimental import Broadcast
from usys import stdin
from uselect import poll
from umath import sin, cos, tan, asin, acos, atan, degrees
 
radio = Broadcast(topics=["INPUT"])
 
hub = InventorHub()
 
WristVertical = Motor(Port.A, Direction.CLOCKWISE, [[16, 20], [1,8], [8, 60]])
WristTorsion = Motor(Port.B, Direction.COUNTERCLOCKWISE, [[8, 24], [8, 60]])
Claw = Motor(Port.C)
ElbowR = Motor(Port.E, Direction.COUNTERCLOCKWISE, (1,60))
ElbowL = Motor(Port.D, Direction.COUNTERCLOCKWISE, (1,60))
Sensor = ColorDistanceSensor(Port.F)
 
CalClaw = 0
CalibrationElbow=0
CalibrationWrist = 0
 
print("Calibrate Elbow? (Yes=LEFT, No=RIGHT)")
pressed = []
while not any(pressed):
    wait (10)
    pressed = hub.buttons.pressed()
if Button.LEFT in pressed:
    Tilt=int(hub.imu.tilt()[0])
    if Tilt > 1:
        ElbowR.run(-5)
        ElbowL.run(-5)
    if Tilt < 1:
        ElbowR.run(+5)
        ElbowL.run(+5)
    while CalibrationElbow == 0:
        Tilt=int(hub.imu.tilt()[0])
        print(Tilt)
        wait(100)
        if Tilt == 0 :
            wait(500)
            ElbowR.brake()
            ElbowL.brake()
            ElbowR.reset_angle(0)
            ElbowL.reset_angle(0)
            CalibrationElbow =1
            wait(1000)
            Tilt=int(hub.imu.tilt()[0])
            print("Elbow calibrated")
            print(Tilt)
            hub.light.blink(Color.GREEN, [500, 500])
            wait(3000)
            hub.light.off()
    while CalibrationWrist == 0:
        WristTorsion.run(20)
        color = Sensor.color()
        if color == Color.YELLOW :
            wait(150)
            WristTorsion.stop()
            print("Torsion Calibrated")
            wait(1000)
            CalibrationWrist = 1
            hub.light.blink(Color.GREEN, [500, 500])
            WristTorsion.run_angle(20,180)
            WristTorsion.reset_angle(0)
            wait(3000)
    while CalibrationWrist == 1 :
        WristVertical.run(-10)
        dist = Sensor.distance()
        print(dist)
        if dist == 90 :
            WristVertical.stop()
            print("Vertical calibrated")
            hub.light.blink(Color.GREEN, [500, 500])
            wait(3000)
            WristVertical.run_angle(20, 60)
            WristVertical.reset_angle()
            CalibrationWrist = 2
if Button.RIGHT in pressed :
    print("Calibration skipped")
    CalibrationWrist = 2
    CalibrationElbow = 1
while CalClaw == 0:
    info = radio.receive("INPUT")
    if info:
        info1 = info[0]
        if info1 == 0:
            Claw.reset_angle(0)
            print("Claw calibrated (and closed)")
            CalClaw = 1
        Claw.run_target(500, info1)
       
while CalibrationWrist==2 and CalibrationElbow==1 and CalClaw==1:
    info = radio.receive("INPUT")
    if info:
        info1 = info[0]
        info2 = info[1]
        info3 = info[2]
        info4 = info[3]
        Claw.run_target(500, info1, wait=False)
        WristTorsion.run_target(40, info2, wait=False)
        WristVertical.run_target(20, info3, wait=False)
        ElbowR.run_target(10, info4, wait=False)
        ElbowL.run_target(10, info4)
 
       

 

This other one fails, but way less often (the one in the middle):

from pybricks.hubs import InventorHub
from pybricks.pupdevices import Motor, ColorSensor, UltrasonicSensor
from pybricks.parameters import Button, Color, Direction, Port, Side, Stop
from pybricks.robotics import DriveBase
from pybricks.tools import wait, StopWatch
from pybricks.experimental import Broadcast
 
hub = InventorHub()
 
radio = Broadcast(topics=["INPUT"])
 
Shoulder1R = Motor(Port.A, Direction.CLOCKWISE, ([1, 24], [12,140]))
Shoulder2R = Motor(Port.B, Direction.CLOCKWISE, ([1, 24], [12,140]))
Shoulder1L = Motor(Port.C, Direction.COUNTERCLOCKWISE, ([1, 24], [12,140]))
Shoulder2L = Motor(Port.D, Direction.COUNTERCLOCKWISE, ([1, 24], [12,140]))
 
print("Calibrate Shoulder? (Yes=1, No=0)")
pressed = []
while not any(pressed):
    wait (10)
    pressed = hub.buttons.pressed()
if Button.LEFT in pressed:
    Tilt=int(hub.imu.tilt()[0])
 
    if Tilt > 1:
        Shoulder1R.run(-2)
        Shoulder2R.run(-2)
        Shoulder1L.run(-2)
        Shoulder2L.run(-2)
 
    if Tilt < 1:
        Shoulder1R.run(2)
        Shoulder2R.run(2)
        Shoulder1L.run(2)
        Shoulder2L.run(2)
 
    CalibrationShoulder = 0
 
    while CalibrationShoulder < 1:
        Tilt=int(hub.imu.tilt()[0])
        print(Tilt)
        if Tilt == 0 :
            wait(2000)
            Shoulder1R.brake()
            Shoulder2R.brake()
            Shoulder1L.brake()
            Shoulder2L.brake()
            Shoulder1R.reset_angle(0)
            Shoulder2R.reset_angle(0)
            Shoulder1L.reset_angle(0)
            Shoulder2L.reset_angle(0)
            CalibrationShoulder =1
            hub.light.blink(Color.GREEN, [500, 500])
            wait(3000)
            print("Calibration completed")
if Button.RIGHT in pressed :
    CalibrationShoulder = 1
    print("Calibration skipped")
 
while CalibrationShoulder == 1:
    info = radio.receive("INPUT")
    wait(100)
    if info :
        Angle = info[4]
        Shoulder1R.run_target(1000,Angle,wait=False)
        Shoulder2R.run_target(1000,Angle,wait=False)
        Shoulder1L.run_target(1000,Angle,wait=False)
        Shoulder2L.run_target(1000,Angle)
           

 

In sum, the problem is that  quite often, the programs just stop. No message is given. They just stop working. Also,  the program of the master hub -which is the only one that is in communication with the PC- is often also stopped and the connection shut. 

 

Honestly, I have no idea what to do. I would prefer to stay with pybricks and because how much I am learning. Moving to official Lego app, although is a possibity, I would prefer rather not to go. 

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.