X Tutup
Skip to content

EV3-G API infrared sensor#374

Merged
dwalton76 merged 10 commits intoev3dev:developfrom
dwalton76:ev3-api-infrared-sensor
Sep 26, 2017
Merged

EV3-G API infrared sensor#374
dwalton76 merged 10 commits intoev3dev:developfrom
dwalton76:ev3-api-infrared-sensor

Conversation

@dwalton76
Copy link
Copy Markdown
Collaborator

No description provided.

@dwalton76
Copy link
Copy Markdown
Collaborator Author

We have the InfraredSensor functionality split into three classes

  • InfraredSensor
  • RemoteControl
  • BeaconSeeker

but the EV3-G block do all of this via on InfraredSensor block. I like the way we did it much more, it feels much cleaner. Anyway, I moved the functionality from RemoteControl and BeaconSeeker up to InfraredSensor but did so in a way to make RemoteControl and BeaconSeeker backwards compatible.

Copy link
Copy Markdown
Member

@WasabiFan WasabiFan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to re-arrange the classes as they were before so the diff isn't so weird?

ev3dev/core.py Outdated
return value

@property
def auto_mode(self):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? I can't imagine we have anyone using this property... I think we should just remove it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use it in any of the demos...I would be ok with chopping it


self._mode = self.set_attr_string(self._mode, 'mode', value)
self._mode_value = value

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you need to update the getter as well?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True I could just have it return self._mode_value

@dwalton76
Copy link
Copy Markdown
Collaborator Author

Looking into the api_test failure...

ev3dev/core.py Outdated
'_decimals',
'_driver_name',
'_mode',
'_mode_value',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR title says 'Infrared sensor', but this looks like a move to introduce caching for the mode value. Should this be split into a couple of PRs?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will pull this part out into a new PR

@dwalton76
Copy link
Copy Markdown
Collaborator Author

Would it be possible to re-arrange the classes as they were before so the diff isn't so weird?

yep will put them back where they were, we can move them around later via another PR

@dwalton76
Copy link
Copy Markdown
Collaborator Author

Should be easier to read now

ev3dev/core.py Outdated

class InfraredSensor(Sensor):

class InfraredSensor(Sensor):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I be worried?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to look at this for a minute to figure out what in the world this change was. It is because I deleted the blank line between the class InfraredSensor and the """. It is odd that it displayed it that way though

'IR-REMOTE',
'IR-REM-A',
'IR-CAL',
MODE_IR_PROX,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

)

_BUTTON_VALUES = {
0: [],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we get a comment explaining what these indicies are?

Copy link
Copy Markdown
Collaborator Author

@dwalton76 dwalton76 Sep 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about

The following are all of the various combinations of button presses for the remote
control.  The key/index is the number that will be written in the attribute file to
indicate what combination of buttons are currently pressed. 

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

}

#: Handles ``Red Up`` events.
on_red_up = None
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the buttons color-coded? I have never actually used the remote after taking it out of the box 😆

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are all gray but there is a red mark on the remote between the two buttons on the left and a blue mark between the two on the right.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

45508

if self.auto_mode:
self.mode = self.MODE_IR_PROX
# BeaconSeeker
def heading(self, channel=1):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the idea behind making these methods instead of property getters?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is so you can pass the channel that you want...the EV3-G block has this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, duh. Makes sense.

ev3dev/core.py Outdated
Returns heading (-25, 25) to the beacon on the given channel.
"""
self.mode = self.MODE_IR_SEEK
channel = max(1, min(4, channel)) - 1
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warn/error if the channel is out-of-bounds?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I'll put an assert in here...it would be really confusing behavior if someone passed in channel 5

ev3dev/core.py Outdated
def distance(self, channel=1):
"""
Returns distance (0, 100) to the beacon on the given channel.
Returns -128 when beacon is not found.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well duh, of course it returns -128 😆 Do we want to catch that and return None instead? I think no one actually reads our docs 😉

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure...what does the EV3-G block do in this scenario?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning 'None' makes sense.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

return (self.heading(channel), self.distance(channel))

# RemoteControl
def red_up(self, channel=1):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_red_up_pressed? or red_up_pressed? I originally read this thinking that this was asking whether "red" was released.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah the up/down naming convention is a little odd. I don't think we should change this though, we use the RemoteControl a fair amount in the demos, I imagine these are used a lot.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we are not worried about being backwards compatible do we want to change the names of red_up, red_down, etc? IMO they are pretty confusing. Brainstorming....

  • We could label them top_left, bottom_left, top_right, bottom_right
  • We could rename red_up() to is_top_left_pressed(), etc
  • We could rename on_red_up to on_top_left_press, etc

ev3dev/core.py Outdated

#: Handles ``Beacon`` events.
on_beacon = None
def __init__(self, sensor=None, channel=1):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the order we want it in? Or should channel be first? I'd imagine that providing a custom sensor will be quite rare. Not that it really matters as you can reference it by name anyway.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was that way before so we should probably leave it as-is

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR makes the class a subclass of InfraredSensor. Why do we need the sensor parameter (and _sensor field) here at all?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for backwards compatibility

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, the BeaconSeeker class here already is InfraredSensor (since it inherits from it). So why store another instance of InfraredSensor in _sensor?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I support this

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

python zen: "flat is better than nested"

having a single InfraredSensor class sounds like a good call.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should start keeping track of all breaking changes; do you guys want to do that in the changelog file as we go or add a "changelog" section to the README? Or maybe create an issue thread to post into? I'm up for whatever's easiest for you guys.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can start a draft of new release here. It seems README could grow too long too fast if we start putting changes there. Another idea is we could add another section in the documentation for this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting idea! I just created a release where we can try out tracking this; as we merge PRs we should make sure to update it. If this doesn't go well we can try out a more conventional file approach. https://github.com/rhempel/ev3dev-lang-python/releases/tag/untagged-f43144149d22a7d3cc09

Note that the link might break once we add a version tag.

on_red_up = None

#: Handles ``Red Down`` events.
on_red_down = None
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are user-defined event handling functions that should fire up during call to process() method (and by the way, I don't see the method here). As in

def beep_when_pressed(state):
    if state:
      Sound.beep()

rc.on_red_up = beep_when_pressed

while True:
  rc.process()

I don't see how these would work as is, since we are merging RemoteControl with the InfraredSensor, and there is no way to set the channel here (we used to set channel in the constructor of RemoteControl).

We should probably change these into dictionaries: on_press[1] = beep_when_pressed (not lists because channel numbers start at 1).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re process() method: in the RemoteControl class it was inherited from ButtonBase. If we do want to merge RemoteControl with InfraredSensor, we should probably inherit from ButtonBase as well.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gotcha, will test/work on this part this evening

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is working now

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How exactly does it work now? Where do we specify channel to use with the handles?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prior to this PR you would need to create a RemoteControl object for each channel that you wished to define handlers for.

Yes, that is correct. But the new implementation of infrared sensor allows to (or claims to) be channel-independent: channel is passed to methods like heading() or process() instead of being assigned at construction. But for RC handlers to work with different channels users would have to create an instance of InfraredSensor per channel, which does not seem logical. I think we could drop ButtonBase from parents, and reimplement the functionality so that handlers would take not just state, but also channel, or something to the same effect?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we think that supporting per-channel handlers in a single object is something folks will use

I used this ability for the big shooting robot (EV3STORM?). One channel for leg movement, the other for shooting. It does come handy from time to time.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Are you ok if we merge this PR and file a new issue to add per-channel capabilities to the handlers? We are at 10 commits and 60+ comments on this PR and short of the per-channel handlers I think it is in pretty good shape.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do that, it seems in good shape otherwise.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #380 for this part

ev3dev/core.py Outdated


class RemoteControl(ButtonBase):
class RemoteControl(ButtonBase, InfraredSensor):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should either drop RemoteControl and BeakonSeeker or keep everything as is. The classes do not do anything that InfraredSensor already does not, so why keep them?.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed they aren't doing much but we need them for backwards compatibility

@ddemidov
Copy link
Copy Markdown
Member

ddemidov commented Sep 26, 2017

Now that we are not worried about being backwards compatible do we want to change the names of red_up, red_down, etc? IMO they are pretty confusing. Brainstorming....

I like left_top or red_top, side (left/red or right/blue) in front. I see the side being more important, because there is builtin color coding, and the whole side (red/left or blue/right) is usually dedicated to a motor.

@dwalton76
Copy link
Copy Markdown
Collaborator Author

What do you guys say we go ahead and merge this one and we can kick around renaming red_up, etc via another PR? If we rename them we will only be able to do so in certain parts of the code because the kernel will still use red_up, red_down etc. I'm worried we might make things more confusing...I didn't think about this until after we had already started kicking around names though that is why I didn't bring it up earlier.

Thank you for all of the feedback on this PR, I think this is the most comments I've seen on a single PR here :) I like where we ended up, it looks much cleaner now and is 1:1 with the EV3-G block.

Copy link
Copy Markdown
Member

@WasabiFan WasabiFan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remember to add this to the draft release for VNext.

@dwalton76 dwalton76 changed the title Ev3 api infrared sensor EV3-G API infrared sensor Sep 26, 2017
@dwalton76 dwalton76 merged commit 390da18 into ev3dev:develop Sep 26, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

X Tutup