pybricks / support

Pybricks support and general discussion
MIT License
109 stars 7 forks source link

[Bug] ev3 loop time issues with v3.X #1035

Open kai-morich opened 1 year ago

kai-morich commented 1 year ago

looks like some initialization is still ongoing, when the program is started

the issue does not occur with v2.3.2 or with prime-hub at v3.3.0b3 or v2.3.2

#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import Motor
from pybricks.parameters import Port, Stop, Direction
from pybricks.tools import wait
from pybricks.robotics import DriveBase

hub = EV3Brick()
left_motor = Motor(Port.C, positive_direction=Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.D)
drive = DriveBase(left_motor, right_motor, wheel_diameter=63, axle_track=91)

#print()
#wait(10)
hub.speaker.beep()
drive.straight(100, then=Stop.NONE)
drive.curve(150, -20, then=Stop.NONE)
drive.straight(100, then=Stop.NONE)
drive.curve(150, 20, then=Stop.NONE)
drive.straight(100)
hub.speaker.beep()
laurensvalk commented 1 year ago

This is due to https://github.com/pybricks/pybricks-micropython/pull/146.

We can open a new issue if timing becomes an issue elsewhere. (like the beep mentioned above)

Originally posted by @laurensvalk in https://github.com/pybricks/pybricks-micropython/issues/146#issuecomment-1441696690

So thanks for opening this issue, @kai-morich :)

kai-morich commented 1 year ago

I also noticed other strange behavior in a more complex program used for WRO 23 season when using v3.3b instead of v3.2. I will try to isolate and create a testcase. Can the timing issue also affect the later program execution?

kai-morich commented 1 year ago

this test programm

#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import Motor
from pybricks.parameters import Port, Direction
from pybricks.tools import wait, StopWatch
from pybricks.robotics import DriveBase

ev3 = EV3Brick()
left_motor = Motor(Port.C, Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.D, Direction.CLOCKWISE)
robot = DriveBase(left_motor, right_motor, wheel_diameter=62, axle_track=195)
stopwatch = StopWatch()

# drive forward, e.g. with line / wall follower
print('a', stopwatch.time(), robot.distance())
robot.reset()
print('b', stopwatch.time(), robot.distance())
while robot.distance() < 100:
    print('c', stopwatch.time(), robot.distance())
    robot.drive(200, 0)
    print('d', stopwatch.time(), robot.distance())
    wait(10)
print('e', stopwatch.time(), robot.distance())
robot.stop()
print('f', stopwatch.time(), robot.distance())

works well with v.3.2.3 and produces this output

Starting: brickrun --directory="/home/robot/drive_test" "/home/robot/drive_test/main.py"
----------
a 0 0
b 13 0
c 23 0
d 26 0
c 39 0
d 40 0
c 58 0
d 61 0
c 80 2
d 82 2
c 99 4
d 102 4
c 115 4
d 121 5
c 137 5
d 139 5
c 156 7
d 158 7
c 170 9
d 172 9
c 186 11
d 192 11
c 206 13
d 208 14
c 223 15
d 226 16
c 240 18
d 242 18
c 267 22
d 270 23
c 283 25
d 288 26
c 307 29
d 309 29
c 321 31
d 323 32
c 340 35
d 343 35
c 361 39
d 363 39
c 377 42
d 384 43
c 406 47
d 407 48
c 421 50
d 423 51
c 441 54
d 443 54
c 457 57
d 459 58
c 473 60
d 476 61
c 493 64
d 495 65
c 513 68
d 518 69
c 535 72
d 537 73
c 554 76
d 559 77
c 578 80
d 580 81
c 592 83
d 595 84
c 613 87
d 622 89
c 635 91
d 637 92
c 657 95
d 659 96
c 673 98
d 676 99
e 693 101
f 694 102
----------
Completed successfully.

but is basically unusable with v3.3.0b3 and produces this output

Starting: brickrun --directory="/home/robot/drive_test" "/home/robot/drive_test/main.py"
----------
a 0 0
b 1722 0
c 1722 0
d 1727 0
c 1823 0
d 1824 0
c 1924 8
d 1927 9
c 2103 46
d 2104 47
c 2154 59
d 2154 59
c 2334 99
d 2334 100
e 2644 156
f 2647 156
----------
Completed successfully.

even with adding some longish wait or beep or drive.straight before, it doesn't get better

dlech commented 1 year ago

Hi @kai-morich

Can you please try pybricks-micropython-build-2735.zip and see if it fixes the issue?

kai-morich commented 1 year ago

thanks for the fix, works again!

Starting: brickrun --directory="/home/robot/drive_test" "/home/robot/drive_test/main.py"
----------
a 0 0
b 15 0
c 21 0
d 22 0
c 34 0
d 35 0
c 52 0
d 54 0
c 65 1
d 72 1
c 84 1
d 84 1
c 99 3
d 101 3
c 112 3
d 113 3
c 125 4
d 127 4
c 145 5
d 146 5
c 161 6
d 162 6
c 179 7
d 179 7
c 195 8
d 196 8
c 212 10
d 218 11
c 231 13
d 232 13
c 244 14
d 245 14
c 264 17
d 265 18
c 279 20
d 284 20
c 295 22
d 296 22
c 313 24
d 314 24
c 332 27
d 334 28
c 349 30
d 349 30
c 361 32
d 362 32
c 375 34
d 379 35
c 392 37
d 393 37
c 405 38
d 408 39
c 421 41
d 426 41
c 439 43
d 440 44
c 452 45
d 453 45
c 469 48
d 469 48
c 481 50
d 486 50
c 498 52
d 499 52
c 511 54
d 520 55
c 532 57
d 533 57
c 549 59
d 551 60
c 564 62
d 565 62
c 580 64
d 582 64
c 595 66
d 598 67
c 610 69
d 611 69
c 622 70
d 624 71
c 636 73
d 638 73
c 657 76
d 662 77
c 680 80
d 681 80
c 693 82
d 694 82
c 708 84
d 709 84
c 721 86
d 722 87
c 734 89
d 735 89
c 752 92
d 754 92
c 772 95
d 774 95
c 788 98
d 789 98
e 801 100
f 802 100
----------
Completed successfully.
dlech commented 1 year ago

FYI, build 2735 had some issues.

I've made a 2nd attempt.

See https://github.com/pybricks/pybricks-micropython/pull/161#issuecomment-1528123328 for latest builds.

kai-morich commented 1 year ago

with build-2738 runs much smoother than build-2735

dlech commented 1 year ago

We've also made https://github.com/pybricks/pybricks-micropython/pull/164 which should improve the control even more.

dlech commented 1 year ago

Build for testing: https://github.com/pybricks/pybricks-micropython/pull/164#issuecomment-1531746503 (includes both changes)

kai-morich commented 1 year ago

build 2756 has a new issue:

laurensvalk commented 1 year ago

test at https://github.com/pybricks/support/issues/1056 fails with: File "/home/robot/reverse_test/main.py", line 15, in set_speed OSError: [Errno 1] EPERM:

That program doesn't seem quite right:

from pybricks.hubs import EV3Brick
from pybricks.pupdevices import Motor

hub = EV3Brick()
left_motor = Motor(Port.E, positive_direction=Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.F)

Which hub is this? EV3 has no pupdevices or port E and F.

Can you share the program that reproduces an error on EV3?

kai-morich commented 1 year ago

sorry, I just partly changed test code at #1056 from spike to ev3. now should be fully updated

laurensvalk commented 1 year ago

It's still using pupdevices. Since that issue is closed, it would be great if you can share a program here that reproduces the problem. I don't seem to get the EPERM error.

kai-morich commented 1 year ago

now i have fully overwritten the #1056 example with the program i used

kai-morich commented 1 year ago

I remember to have seen EPERM also with v2.0.0 when i tested #1056. For that old version I moved the set_speed() to the beginning of the program.

with stop() before set_speed() the new version works.

laurensvalk commented 1 year ago
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import Motor
from pybricks.parameters import Port, Direction, Color
from pybricks.robotics import DriveBase
from pybricks.tools import wait

hub = EV3Brick()
left_motor = Motor(Port.C, Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.D, Direction.CLOCKWISE)
robot = DriveBase(left_motor, right_motor, wheel_diameter=62, axle_track=195)

def set_speed(speed):
    robot.settings(speed, speed*8, speed//2, speed*5 )

# drive forward with line / wall follower controlled turn_rate
hub.light.on(Color.YELLOW)
robot.reset()
while robot.distance() < 100:
    robot.drive(300, 0)
    wait(10)

# stop
hub.light.on(Color.GREEN)
#robot.stop() # <---
#wait(100)    # <---

# drive back
hub.light.on(Color.RED)
set_speed(100)
robot.straight(-100)
laurensvalk commented 1 year ago

I remember to have seen EPERM also with v2.0.0

Yes, back in 2.0.0 changing the settings was not allowed while driving. This is allowed now. So we can skip that issue then.

laurensvalk commented 1 year ago

That leaves us with:

test at this issue has very bumpy drive speed

Is the following better? Can you describe bumpy drive speed?

pybricks-micropython-build-2763

kai-morich commented 1 year ago

2763 works again

bumpy: never reached normal speed. accelerated + deacellerated 2-3 times with 1 second period

laurensvalk commented 1 year ago

Could I kindly ask for video? Thanks in advance.

kai-morich commented 1 year ago

ok

laurensvalk commented 1 year ago

Can you modify the following program to reproduce your issue?

from pybricks.ev3devices import Motor
from pybricks.tools import wait
from pybricks.parameters import Port, Direction
from pybricks.robotics import DriveBase
from pybricks import version

print(version)

# Initialize.
left_motor = Motor(Port.C, Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.D, Direction.CLOCKWISE)
robot = DriveBase(left_motor, right_motor, wheel_diameter=62, axle_track=195)

# Allocate logs for motors and controller signals.
DURATION = 6000
left_motor.log.start(DURATION)
right_motor.log.start(DURATION)
drive_base.distance_control.log.start(DURATION)
drive_base.heading_control.log.start(DURATION)

#
#
# Add some code here to make some moves that reproduce your problem. For example:
drive_base.straight(500)
drive_base.straight(-500)
#
#

drive_base.stop()

# Save data logs.
print("Saving data on the EV3...")
left_motor.log.save("servo_left.txt")
right_motor.log.save("servo_right.txt")
drive_base.distance_control.log.save("control_distance.txt")
drive_base.heading_control.log.save("control_heading.txt")
print("Done")

This will produce a few text files on your EV3. If you want to share them here, we can find out what is going on.

kai-morich commented 1 year ago

sorry, too many test programs.

bumpy happened with the second test program:

#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import Motor
from pybricks.parameters import Port, Direction
from pybricks.tools import wait, StopWatch
from pybricks.robotics import DriveBase

ev3 = EV3Brick()
left_motor = Motor(Port.C, Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.D, Direction.CLOCKWISE)
robot = DriveBase(left_motor, right_motor, wheel_diameter=62, axle_track=195)
stopwatch = StopWatch()

# drive forward, e.g. with line / wall follower
print('a', stopwatch.time(), robot.distance())
robot.reset()
print('b', stopwatch.time(), robot.distance())
while robot.distance() < 100:
    print('c', stopwatch.time(), robot.distance())
    robot.drive(200, 0)
    print('d', stopwatch.time(), robot.distance())
    wait(10)
print('e', stopwatch.time(), robot.distance())
robot.stop()
print('f', stopwatch.time(), robot.distance())

https://user-images.githubusercontent.com/25850372/235757327-48a8a68e-2ecf-4ed7-a074-17c9c451f5cf.mp4

will test the other programm and then add logs to the bumpier one

kai-morich commented 1 year ago

build 2756 looks incomplete: ImportError: no module named 'pybricks.version' AttributeError: 'Control' object has no attribute 'log'

older + newer builds are not bumpy

laurensvalk commented 1 year ago

Thanks. I can reproduce one form of "bumpy" behavior. It looks like some loops are still taking too long.

image

kai-morich commented 1 year ago

👍

dlech commented 1 year ago

I think it was a glitch that this was automatically closed. There are still some issues as shown in the plot by Laruens.

jaguilar commented 1 year ago

There is some commentary here or there that there are plans to try to get ev3 back to supported status in the next release of pybricks. However I'm told in #1215 that this is no longer the case. I wonder if we should add a warning to the console to make this clearer on initialization if someone is using a firmware that is not only not-yet-supported, but also actively never-gonna-be-supported.

For example #1075 suggests that getting a v3 firmware onto an ev3 is a thing that someone might want to do, but given there are no plans to make v3 work on ev3, it probably doesn't actually make sense for people to go through the trouble of testing it.

If this makes sense to people I could send a pull request.

laurensvalk commented 1 year ago

Instead of modifying the build, I think we can just add a note to those (somewhat outdated) instructions.

And it looks like you have done so, so thanks for that!

It would certainly be nice to see the EV3 version continue to be supported. See also https://github.com/orgs/pybricks/discussions/1171#discussioncomment-6516689 for additional context.

jaguilar commented 1 year ago

Sure, that makes sense. And I totally understand the constraints involved with no supporting v3 on ev3 -- y'all have a limited amount of time to spend on the project and it definitely makes more sense to spend it on whatever is being used most today.

It does look like the _thread module will help with most of the things that I wanted to upgrade to v3 for -- the multitasking stuff. It's a little unfortunate that if/when I upgrade to spike prime, I'll need to change my code a bit to maximize efficiency, but it's definitely manageable.

winklerp commented 1 year ago

I would also highly appreciate if EV3 would be supported again by v3.3 since I have a lot of 3rd party sensors and add ons for it! Also communication between different hubs EV3 <-> Spike, … would be very nice! 👍

winklerp commented 1 year ago

Any chance to get this fixed vor v3.3?

laurensvalk commented 1 year ago

No, this is not planned for V3.3 I'm afraid.

We don't seem to have enough EV3 users / sponsors / volunteers at the moment to work on this.

I would rather work on a revised firmware (either bare metal or non-SD-card-Linux), and get all the new features supported there, instead of patching the existing 2.0 edition that seems to work well enough for most users.

That way, the EV3 edition can eventually blend in with the rest of Pybricks (including web IDE) instead of treating it separately. Although not actively requested here on Github, this is requested a lot by people/teachers who would like a good and simple solution for EV3.

Then the stable 2.0 edition with vscode and all ev3dev iOT capabilities can continue to exist with its existing documentation, and hosting / support from LEGO Education, without ever making any breaking changes.

BertLindeman commented 1 year ago

No, this is not planned for V3.3 I'm afraid.

We don't seem to have enough EV3 users / sponsors / volunteers at the moment to work on this.

I would rather work on a revised firmware (either bare metal or non-SD-card-Linux), and get all the new features supported there, instead of patching the existing 2.0 edition that seems to work well enough for most users.

That way, the EV3 edition can eventually blend in with the rest of Pybricks (including web IDE) instead of treating it separately. Although not actively requested here on Github, this is requested a lot by people/teachers who would like a good and simple solution for EV3.

Then the stable 2.0 edition with vscode and all ev3dev iOT capabilities can continue to exist with its existing documentation, and hosting / support from LEGO Education, without ever making any breaking changes.

Keeping 2.0 version stable and to add EV3 to the code.pybricks.com family would be very nice. Would really like that.

I have the EV3 still running as linux host, but it's just running for fun. The linux version (ev3dev-stretch) is lagging behind a bit. Stretch went out of support June 2022.

winklerp commented 1 year ago

I would rather work on a revised firmware (either bare metal or non-SD-card-Linux), and get all the new features supported there, instead of patching the existing 2.0 edition that seems to work well enough for most users.

That way, the EV3 edition can eventually blend in with the rest of Pybricks (including web IDE) instead of treating it separately. Although not actively requested here on Github, this is requested a lot by people/teachers who would like a good and simple solution for EV3.

That would be an awesome solution but sounds like way more work and might also take longer than getting the current version running again even if not "officially" supported.

laurensvalk commented 1 year ago

I don't think there's a quick fix/hack available if that's what you're asking.

The current iteration of motor drivers were designed for bare metal systems with simple timing, so it is not expected to work as-is on EV3 (Linux). That is to say, this isn't just some random bug.

This was intentional / by design: the drivers have been a huge step forward on all platforms that have ongoing releases.

And nothing is really broken on 2.0 either, it just didn't get all the new features.

While it's probably technically possible to revise the control algorithms for non-rt systems, it doesn't seem worth investing a lot of time that could be used elsewhere.

Perhaps taking a step back, what are the main use cases for V3.3? Is it only certain drive functions? Could they be implemented using a Python class?

Due to the nature of the hardware, control precision is quite good on EV3 in 2.0, both for single and dual motors. So it shouldn't be too hard to implement things like curve with a radius, and make them non-blocking with the wait=False paradigm used elsewhere.

kai-morich commented 1 year ago

I like the curve function and then=Stop.* options introduced after V2.0. Both could very likely be implemented in python on top of V2.0.

What is the latest version you can seriously recommend for EV3?

When were the new motor drivers introduced? In V3.3 or earlier? I used V3.2 quite succefully, besides bug #1056 that happened sometimes when reversing the direction.

laurensvalk commented 1 year ago

What is the latest version you can seriously recommend for EV3?

I would recommend the official version hosted by LEGO Education, so Pybricks 2.0.

I like the curve function and then=Stop.* options introduced after V2.0. (...) When were the new motor drivers introduced?

These features were introduced alongside the new drivers in 3.3.

Both could very likely be implemented in python on top of V2.0.

:+1:

Rest assured, we won't forget about EV3. Just trying to keep expectations realistic :smile: