A "moveTank()" kind of drivebase movement #1156
Replies: 8 comments 5 replies
-
Just curious, could this not be done with any of the existing methods? You could steer slightly if you want to push against a wall. What are the limitations of doing it this way? EDIT: Maybe I see what you mean. Could you elaborate on the use case? Is the main reason to push slightly against a wall, or are there other benefits for having a tank drive as well? Just trying to better understand the use cases so we can add good functionality for everyone :) |
Beta Was this translation helpful? Give feedback.
-
To elaborate on the wall following, consider a robot on the table with its right side flat against the wall. If I drive the left motor forward at speed 50 (units are irrelevant, so call it 50% of the max), and drive the right motor forward at speed 45, this will drive the robot forward while slightly pushing on the wall, and ensure it stays flat against the wall. So of course there's the consideration of when to stop. A decision needs to be made internally as for which motor will be the one to decide if the robot has driven the full distance. Commonly we use degrees or rotations to track the distance. We would normally choose the faster motor because there is a use case for using the moveTank() with a speed of zero for one motor. This is very very rare (holding one wheel while driving the other), but just because my team has never done this, that wouldn't mean no teams would. Alternatively, a team could use time instead of rotations/degrees to decide when to stop. I guess to really do it right in pybricks style, I would make a "wait" boolean parameter, in which case the command would be called, but the execution of the code would continue right away without waiting for the drive to end. Same for the "then" parameter, like the other pybricks drive commands (COAST, BRAKE, HOLD, etc). Also, it might be worth giving an option to start the moveTank() with no ending parameters. In which case it would be up to the programmer to come up with the stopping code. This would be more like drive forever. So maybe there is a driveTank() which drives forever, and a moveTank() which requires ending parameters. I think there is one other use case. We call it wall squaring, and a lot of teams do this too. For robots that are square in shape, they can drive (forwards or backwards) straight into the wall with the understanding that the robot will probably not hit it perfectly straight. Say the left front corner of the robot hits the wall first. If the robot continues to drive for another half second or so, this will have the tendency to square-up the robot. One other smaller use case is very similar to wall squaring. Sometimes we may drive a long distance, perhaps using gyrodrive. Then when we get close to the target, say a mission model that is attached to the table, we slow down and use a moveTank method to gently hit the model. We don't want any external steering attempts to happen, we just want to hit the model so we know precisely that we have traveled the whole way and we are in position to do whatever is next. Again, pretty similar to wall squaring, but just a little different in the application. I hope this helps! Skip |
Beta Was this translation helpful? Give feedback.
-
For the wall squaring, the wheels run at the same speed. We usually like to use time as a parameter when squaring because every once in a while the wheels will stop instead of slip (you WANT the wheels to slip here). And if the wheels stop, which can happen since the robot is driving into an immovable object, especially if the robot is carrying something heavy-ish, the program will get stuck on that line. Sure, there's stall detection and there's drive(), but these can all be handled by the same moveTank as described above. At least with a time parameter we know the robot will be moving again after the given time elapses. I also looked at the curve function, and that will work, but the current units/parameters won't make sense to Middle School kids. Your veer function suggestion sounds much better and will probably meet our needs. I think with your prototype code, the turn_rate would be positive to veer right and negative to veer left (the docs don't say this so I may be wrong here). And assuming that a turn_rate of zero means just drive both wheels at the same speed? Intuitively, I would think numbers in the +/- 1 to 10 degrees per second turn rate would suffice for most situations (untested). Again, we'll probably look for an option to handle this with time instead of distance because sometimes we just prefer it that way. So yeah, I think your veer() suggestion could work great for wall following. Maybe think about having a veer forever kind of thing where the programmer will have to figure out how to end it, and also think about adding a time option instead of distance/degrees. Finally, I like then "then" and "wait" options on the straight() method, and I think they'd be useful here too. I had not seen the use_gyro() method. That could make this whole thing a lot easier. By the way, thanks for the help here! Super nice getting responses so quickly :) |
Beta Was this translation helpful? Give feedback.
-
Correct. See the top of this page for direction conventions: https://docs.pybricks.com/en/latest/robotics.html
Not specifically here, but I'm generally unsure about providing time functions for all motions (this would double the number of available methods). Is it much of a convenience compared to start+wait+stop? The def drive_for_time(speed, turn_rate, time):
robot.drive(speed, turn_rate)
wait(time)
robot.stop()
Glad to hear it. If you try this new functionality, please let us know how it goes!
Likewise, thanks for reporting your findings from FLL. This helps us really get to the functionality that our users want most. |
Beta Was this translation helpful? Give feedback.
-
I think your suggestion for using time as a parameter is solid. No need for you to make any changes. We will just include some new methods like your suggestion in our baseRobot class as needed. |
Beta Was this translation helpful? Give feedback.
-
@laurensvalk , how do we use the use_gyro(False) command? It doesn't come up in the intellisense code completion. If I am using a gyroDriveBase, are there any limitations on when I can and can't use it? |
Beta Was this translation helpful? Give feedback.
-
Do I run it on an instance of a GyroDriveBase class? Like this?
The intellisense code completion isn't picking this up in VS code. All of the other commands are working fine with the code completion. |
Beta Was this translation helpful? Give feedback.
-
Resurrecting an old thread here. We did end up using the wall following, but we didn't like it very much. With drive(), you don't get the acceleration & deceleration. We are thinking about using curve() instead, with use_gyro(False). The thing is, for the distances that we typically use (like maybe 200mm or less), and for the radius that we would probably use (like 1000mm???) because we don't need a huge movement, just a subtle press, the angle would only be a degree or two. It would be nicer if we could use Straight(), but with a veer angle. Putting a veer parameter in a function called Straight() seems a little strange, but I guess it is OK. Of course, a separate Veer() drivebase function would be nice. Thoughts? |
Beta Was this translation helpful? Give feedback.
-
For FLL, a common way of moving on the table is wall following. With this, you set your outside drive motor a tiny bit faster than the inside drive motor, thus forcing the robot to ride against the wall which it is following. The amount of delta between them can change from application to application, depending on how much force is needed (heavier attachments may need more delta, for example). I'd like to have a way to do this in pybricks. A moveTank method would probably need four parameters: leftMotorSpeed, rightMotorSpeed, amount and units. The motor speeds could be in units of degrees per second or RPM. The "units" parameter would be a string and one of "mm", "degrees", or "seconds", depending on what the programmer needed. The "amount" parameter could be a number reflecting the value needed in the units provided. Of course you could also go with something like MoveTankForSeconds() and MoveTankForDistance() and not have to worry about the units parameter. One other possible option could be to use or not use acceleration, so maybe a boolean flag for that. Personally, I'd be ok with no acceleration, but for sure some teams will want it at some point.
I don't see an easy way to do this with either of the current driveBase options, and instead we need to write our own using direct motor control. I think this would be a popular feature with FLL teams and I hope you will consider adding it.
Beta Was this translation helpful? Give feedback.
All reactions