Sensor framework design

This is where you talk about the EV3 software itself, installation issues, and programming talk.

Moderators: roger, gloomyandy, skoehler

Sensor framework design

Postby hugheaves » Mon Jan 20, 2014 4:21 am

First of all, I'd just like to say a quick thanks for all the hard work that has gone into creating a new version of lejos for EV3. I've been using Lejos since the RCX version, and have always thought that it offers the best (by far) of all the PB programming environments.

That said, I'd like to "chime in" with some comments on the design of the new framework. Hopefully, as this is at the alpha stage, these comments will taken as "constructive feedback" instead of ungratefulness. :)

First, a fairly minor thing: Some of Lejos core API's are declared using concrete collection types, instead of the equivalent collections interface type. Declaring with the interface type is usually considered best practice as it reduces coupling. For example, unless there's a good reason to force everyone to specifically use ArrayList to interact with an API (versus LinkedList, ImmutableList, etc), methods should be declared using List instead of ArrayList.

For example, SensorModes:

Code: Select all
public interface SensorModes
{
    public ArrayList<String> getAvailableModes();
...
}

This interface should probably be changed to:

Code: Select all
public interface SensorModes
{
   public List<String> getAvailableModes();
...
}


For one thing, specifying ArrayList makes it much more difficult to return an immutable list from the method (which this API probably should). ArrayList can, of course, still be returned by this interface method if the return type is declared as "List".

Second, I really like the filters concept, and definitely agree with the design goal of a uniform sensor interface. However, I think "uniform" shouldn't neccessarily mean that the framework uses a lowest common denominator approach (an array of floats) to represent sensor data. Using an array of floats as a core abstraction is not far removed from just representing all sensor data as raw byte arrays.

With "bare" floats, the sensor data becomes esentially typeless (or meaningless). There is nothing inherent in the code or API that indicates how the data should be interpreted or processed. (ie. is this value a temperature, or a distance? is the third value the z coordinate, or the second value? which of these floats represents GREEN?, etc.) The only way to ensure the correct usage is to rely on some external documentation that (as well as being hopefully 'up to date') details the actual representation of the data.

Also, even if I understand what my array of floats actually means, for certain types of data, floats are still not really appropriate. How do I store a barcode in a float? Or a discrete value from a color sensor?

The ability to encapsulate data in new types (classes), and implement meaningful and correct behavior on and around that data is one of the main benefits to programming in Java. With this in mind, I would like to suggest a revision to one of the core sensor API's:

Instead of dealing with float arrays in "SensorProvider":

Code: Select all
interface SensorProvider {
   @Override
    public void fetchSample(float[] sample, int offset)
}


Can we instead use lists of a new type called "Sample".
Code: Select all
interface SensorProvider {
   @Override
    public void fetchSample(List<Sample>sample, int offset)
}


Sample would be the supertype of whatever data types could be returned by sensors. (i.e. Temperature, Distance, Color, Charge, etc.). Furthermore, although we could create our own type system for sensor data samples, why not leverage one of the existing API's that has very nice support for standard "units of measurement"? I feel like that would add some sophistication to the sensor API versus using float arrays.

One such API is the JSR-275 "Units of Measurement" API, which although was never ratified as a JSR standard, has well supported implementations. One such implementation is JScience. To get a feel for the API, take a look at the javadoc for the "quantity" package:

http://jscience.org/api/javax/measure/q ... mmary.html

It includes some very nice types: angles, distances, temperatures, frequencies, etc. All things that sensors return. Even if you decide that the javax.measure API is too heavyweight for Lejos, I still think the API has some good ideas that could be rolled into a lighter weight implementation.

Anyway, it's just food for thought, and I hope you don't mind me putting in my two cents.

Hugh
hugheaves
New User
 
Posts: 15
Joined: Sun Dec 29, 2013 5:35 pm

Re: Sensor framework design

Postby Aswin » Mon Jan 20, 2014 8:25 am

Hi Hugh,

Thanks for the feedback. It is most welcome.

You have two major points. The first is about using generics. I think that others can better respond on this as I have not participated in discussions regarding this. I do know however that support for generics is relatively new in LeJOS. This might explain why most of the API does not support this. But it does not nececerally explain why new parts of the API don't use it.

The second point is about samples and why these are stored as a meaningless floats instead of using a sample object. Here too part of the explanation lies in the past. The framework was designed (but never implemented) for the NXT. The overhead of using objects was considered too big, both in terms of memory and garbage collection. But there are also more fundamental arguments as wel. Consider filters, these are currently very generic. They would be hard to develop when they would have to deal with samples of different data types. Also, when samples would be more meaningful then filters would be responsible of maintaining this meaning. An integration filter would need to change the quantity of a sample, others should change the unit , etc. we doubted that this would be the right path. We therefore decided to keep filters as ignorant as possible and let this to the programmer be responsible of doing the right thing with filters.

Having said that, I must say we often recognized and discussed the benefits of metadata and more meaningful ApI's, whether it was quantity, unit, range, resolution, timestamp or data quality. We also admitted that this API doesn't fit everything. Things like color id can be made to fit in technical terms, but not logically. For now we have decided to fit this in anyway. Other types of samples, like object shape from a visual sensor for example, won't fit in at all. For this we have foreseen the need of a sample object. But for the moment we consider this out of scope. There is also another class of sensors that are more like HIDs (think of a remote control) that also do not fit. I don't think these kind of sensors will ever become part of the framework.

So in short. We do recognize the issues you mention and we even agree on the kind of solution you propose. But for now we let simplicity prevail.


Btw. Some of the standards we use are described in the javadoc of the SampleProvider interface.

<edited for readability>

Aswin

Aswin
My NXT blog: http://nxttime.wordpress.com/
Aswin
leJOS Team Member
 
Posts: 186
Joined: Tue Apr 26, 2011 9:18 pm
Location: Netherlands

Re: Sensor framework design

Postby skoehler » Mon Jan 20, 2014 9:09 pm

Let me first discuss the issue ArrayList vs. List. Returning List is very convenient for the implementor of the method that returns the list, however, it's inconvenient for the programmer that calls the method, since the programmer doesn't know which type of list (array or linked) he gets. They both have strengths and weaknesses.
As to returning read-only lists: Yes, maybe we should. It might be easiest however to return a new copy of a list every time. That particular method is not performance critical. getSensorModes could look like this:
Code: Select all
return Arrays.asList("mode1", "mode2", "mode3");

I'm not sure whether the liste return by asList() is read-only or not. I think it's not (the length is fixed but elements can be modified).
skoehler
leJOS Team Member
 
Posts: 1347
Joined: Thu Oct 30, 2008 4:54 pm

Re: Sensor framework design

Postby skoehler » Mon Jan 20, 2014 9:55 pm

First, Aswin has written a very good summary. But let me state my personal opinion (which may or may not be representative for the leJOS team) on some points you wrote regarding metadata:

At all costs, I would like to avoid an approach that represents one sample with one Object (at least for sensors which are potentially queried many times per second over a long time). This will kill the GC, not only on the NXT but also on the EV3. The only antidote would be to reuse objects. Then again, your Java code working on float arrays will be much faster than code working on object for simple hardware reasons like cache lines and whatnot.

Also, having maximum flexibility with metadata will just encourage that the z-axis is the second value for some sensors but the third for other sensors. All code that deals with data will first have to go through the metadata before it can deal with the data. Then again, there are left and right hand coordinate system, so knowing the axes is not enough. Oh, and then there's the absolute alignment of the axes (i.e. is z really pointing upwards whatever upwards means for the sensor?). All of that has been solved by convention now. That means there is supposed to be one (hopefully never out of date) documentation that basically applies to all sensors. The z axis is always the third value and it's always pointing upwards (if you hold a sensor in a lego case in a certain way). I would have sleepless nights until all of that is solved via metadata. And I don't think it would be easy to use either. Note that in tools like Matlab, Maple, or Mathematica, a vector is basically an array of floats. The model we chose should be natural to anybody that ever used one of these little math helpers.

Data like barcodes doesn't fit the sensor framework. And I admit, the framework wasn't meant for that. For those sensors different solutions are required. Note, that e.g. the filters also won't really be usable for those sensors. In that way, it's not too inconsistent that these sensors can't return the ordinary float[] sample things. Now one could encode a barcode in a float array (one float per character or so) but that would be awkward I guess. We will have to see what to do with them. I really didn't want to go down the road of designing the swiss army knife of sensor frameworks with metadata that allows for every possible kind of data. Keeping things simple might have accelerated having an early leJOS release . (Unfortunately, I can't take any credit for the current releases as I don't have an EV3 yet).

Also regarding units, there was a discussion of the most flexible approach you could dream of. You could configure a sensor to return whatever unit you wish for (for example millimeters instead of centimeters). But again, having a convention instead of glue code (to bridge between producers and consumers which now may work with different units) is simpler (at least code wise) and efficient.

I sure hope everything works out for the best and the framework proves to be usable, reasonably flexible and efficient.
skoehler
leJOS Team Member
 
Posts: 1347
Joined: Thu Oct 30, 2008 4:54 pm

Re: Sensor framework design

Postby hugheaves » Tue Jan 21, 2014 2:54 am

Fair enough, embedded systems design is always a compromise. And if you're backporting the EV3 framework to NXT, that definitely makes a big difference in the overall design constraints.

Regardless, thanks for taking the time to respond to my inquiry, and keep up the good work!

Hugh
hugheaves
New User
 
Posts: 15
Joined: Sun Dec 29, 2013 5:35 pm


Return to EV3 Software

Who is online

Users browsing this forum: Google [Bot] and 1 guest

more stuff