-
Notifications
You must be signed in to change notification settings - Fork 145
Added class MotorSet #336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added class MotorSet #336
Conversation
|
For issue #315 |
| } | ||
| """ | ||
|
|
||
| def __init__(self, motor_specs, desc=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each motor object can tell you what port it's on... why does this need to take a dictionary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The motor objects haven't been created yet though, we need to know what type of objects to make and which ports each of those objects is associated with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I read through the rest of the file then forgot to come back and delete this. I've got it now.
| log.info("%s: %s set %s to %s" % (self, motor, key, kwargs[key])) | ||
| setattr(motor, key, kwargs[key]) | ||
|
|
||
| for motor in motors: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this process (setting the properties then sending commands).
ev3dev/helper.py
Outdated
| motor.wait_while(s, timeout) | ||
|
|
||
|
|
||
| class LargeMotorPair(MotorSet): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should figure out exactly what our goal is. In my mind, the most common scenario will be a pair of large motors which you want to "steer": even if internally we're using a generic MotorSet, I'd like to see if we can make the "pair" classes more specialized so they legitimately feel easy to use and work "out of the box".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah....to me part of it depends on what the user input is to control the steering. If it is the IR remote we have that implemented in the RemoteControlledTank class in helper.py...we could pull some of that code into a Mixin class that could be inherited here in LargeMotorPair. I also did a web interface for a tank, that could be pulled in too but loading the www modules makes the program take a while to load on an ev3. What other user input methods might we see for a MotorPair?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The scenarios I had in mind were:
- "Run the left motor at 50% speed forward and the right motor at 10% speed backward"
- "Run the two motors in a proportion of 3:1" (ratio, differential, etc.)
The second is a special case of the first. Note that the units are nonspecific and just an illustration. The idea is that this class is what's used whenever you have a driving robot... if you want to go straight, turn, spin, etc., you use this.
| self.motors = OrderedDict() | ||
| for motor_port in sorted(motor_specs.keys()): | ||
| motor_class = motor_specs[motor_port] | ||
| self.motors[motor_port] = motor_class(motor_port) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The motor objects are created here
|
|
||
| def run_forever(self, **kwargs): | ||
| kwargs['command'] = ev3dev.auto.LargeMotor.COMMAND_RUN_FOREVER | ||
| self._run_command(**kwargs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I am not sure about is the logic of these run_* functions. Here you are pushing command into kwargs, and then filter it out in _run_command function. This cost a string comparison per key in kwargs, which could be negligible with respect to file acesses, but still is not free.
Why not create _set_args(self, **kwargs) function, and replace the two lines above with
self._set_args(**kwargs)
self._run_command(ev3dev.auto.LargeMotor.COMMAND_RUN_FOREVER)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a set_args() (see line 187) and the user can do it this way if they want but they don't have to.
The price of the string compare feels worth it to me, it let me clean up this code a good bit by moving almost all of the logic to _run_command().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I don't have strong feelings about this, so feel free to merge.
ev3dev/helper.py
Outdated
| """ | ||
|
|
||
| # Set the right_motor speed relative to the left_motor_speed | ||
| if set_right: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, this isn't the behavior I had in mind 😆 I was thinking you would specify a speed and ratio, and it would run the fastest motor at that speed and the other one at a speed defined by the supplied ratio. My thinking was that we'd mimic the "steering" behavior of EV3-G.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't touched EV3-G since the day I found ev3dev :) Does its steering do what ddemidov points to or something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the "synchronized steer" code here, I think I can say that they don't match but @ddemidov's implementation would be preferred. LEGO seems to designate one motor as a "master", drive that one at the requested speed, and then run the other at a rate defined by the steering. I am no expert though so I may be mis-reading it.
ev3dev/helper.py
Outdated
|
|
||
| def set_speed_percentage(self, left_motor_percentage, right_motor_percentage): | ||
| """ | ||
| Set the speeds of the left_motor vs right_motor by percentage of their maximum speed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should specify that the units are -100 to 100. The term "percentage" is often used to refer to [-1,1] or [0,1] by some programmers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack...will also add some asserts to verify the inputs are within the range
ev3dev/helper.py
Outdated
| * 0 means drive in a straight line, and | ||
| * 100 means turn right as fast as possible. | ||
| power: the power that should be applied to the outmost motor (the one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
power? I think this should probably be "speed"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caught that in the initial cut-n-paste....will change all of the power references to speed
ev3dev/helper.py
Outdated
| log.debug("%s: direction %d, power %d, speed %d, left_power %d, right_power %d" % | ||
| (self, direction, power, speed, left_power, right_power)) | ||
|
|
||
| self.left_motor.speed_sp = int(left_power) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't actually run a command here; is the expectation that you call set_speed_steering and then set the command in a loop? Note that updating the setpoint won't have an effect until a command is sent AFAIK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep it will be up to the user to call run_forever, run_timed, etc after this....all this function does is set them up with the desired speed_sp setting. Same goes for set_speed_percentage().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... In that case, we need to make sure we document the behavior!
WasabiFan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good; we need to document the behavior of the new helper functions. I'm approving but I think we want to hold off on merging until we've finalized the v1.0.0 release.
|
Is 1.0.0 out...shall we release the merging floodgates? |
|
Can you add a line to the documentation for Also, is there anything we want to do here in response to #348 (e.g. renaming or changing the behavior to match EV3-G)? |
|
yep will add a line about needing to call For #348 lets tackle any of that via a separate pull request. I need to take a look at what blocks EV3-G has, I'm not sure if the MotorSet class would cover one of them or not. |
The MotorSet class can be used to start/stop more than one motor at once as close together as we possibly can. You can set different params for different motors in the set. Here is a small script I used to try a few things.