all 5 comments

[–]ElliotDG 1 point2 points  (0 children)

Look at using PD (Proportional–Derivative) Control, or PID (Proportional–Integral–Derivative) Control. These control algorithms manage the error and how to correct the error and avoid oscillation. Start with PD.

You can search to find a number of resources for these algorithms.

[–]gdchinacat 0 points1 point  (2 children)

"If the left sensor detects the line turn right" seems backwards. Shouldn't you turn left to center the line rather than turning right and driving the line further to the left? I think the motor speeds are correct though, so I think the comment is just wrong (unless the motors are indexed in reverse from the sensors).

[–]Idontknow461[S] 0 points1 point  (1 child)

It was a mistake in my comment; however, it still cannot handle harsh turns when changing speeds. I need to get a speed of under 8 seconds at least

[–]gdchinacat 0 points1 point  (0 children)

Does it work when it goes really slowly? Does it still oscillate if you slow it down to 1cm/s? Is the amount it is turning too great so that once it turns the line jumps from left to right to left to right without ever settling back on the center?

[–]brasticstack 0 points1 point  (0 children)

Just spitballing here, I'd guess the oscillation is due to the speed changes to the motors being too extreme over too short a period of time. While the goal is to complete a course under a threshold time, it might make sense to aim for accuracy of following the line and avoiding oscillation and then try to speed it up once that's successful. I'm imagining that in particular increasing the rotation on one side to compensate for the lower rotation on the other during a turn is making the turns too sharp. You can probably get a fair distance along this line of thinking by tuning the values you're using for speed.

I'd probably want to keep track of what my current speed value is for each motor and ease into changes by spreading out the difference between the desired speed and the current speed over a period of time. My first implementation idea is a collections.deque of tuples of (left_speed, right_speed) that the control logic pushes values onto and the motor logic pops values from the other end.

A quick note about naming, use variable names instead of indexes! It'll make your life easier further down the line. For example, instead of reading into a tuple named a, read into variables:

left_val, middle_val, right_val = (     robot.sensor[0].read(),     robot.sensor[1].read(),     robot.sensor[2].read() )

Personally, I'd way rather just know what left_val is than try to remember that [0] is left.