Jump to content

Rückgabewerte für analoge Werte in Bindings


Holy

Recommended Posts

Mich würde mal interessieren warum die analogen Werte in den Bindings nicht direkt in die jeweilige Einheit umgerechnet werden? D.h. 1/10 Lux bei z.B. AmbientLight.get_illuminance() statt direkt ein Float in Lux.

Ich denke spätestens in den Bindings hätte es gewisse Vorteile diese Umrechnungen vorzunehmen:

 

1. muss nicht jedes mal durch den Nutzer gemacht werden

2. Änderungen an der Wertigkeit brechen den User-Code, z.B. 1/100 statt 1/10 weil der Sensor genauer ist...

 

Oder gibt es hier gute Gründe für die mir bisher nicht aufgefallen sind?  ;D

Link to comment
Share on other sites

Lustig ist, dass ich heute früh beim Aufstehen darüber nachgedacht habe ;D

 

Also ic denke die Motivation wird es sein, dass du im int oder uint keinen Präzisionsverlust hast, bei float und double könnte sowas passieren.

 

Dennoch fände ich skalierte Werte auch schöner, da ich auch oft ziemlich durcheinander komme. War Humidity jetzt Faktor 10 oder 100? Ich müsste nachschauen.

 

Hier wäre mein Masterplan:

In der Config der Bricks wird je Element eine Spalte für das Scaling eingeführt. So zum Beispiel:

com['packets'].append({
'type': 'function',
'name': ('GetIlluminance', 'get_illuminance'), 
'elements': [('illuminance', 'uint16', 1, 'out', 0.1)],
'doc': ['bm', {
'en':
"""
This is only the doc of the Bricklet...
""",
'de':
"""
"""
}]
})

(neu ist die letzte Spalte bei elements

 

Bindings sind jetzt frei wie sie diese Spalte ausnutzen wollen (bzw. TF darf frei wählen was sie anbieten wollen):

 

public double GetScaledIlluminance()

1.Option: Eine zusätzliche Methode anbieten die skalierte Werte ausgibt (also 20.0 statt 200), die alte bleibt unter altem Namen zusätzlich bestehen wegen der Kompatibilität und Präzision.

 

public double GetRawIlluminance()

2.Option: Die Methode mit altem Namen skaliert per default, aber es gibt noch immer eine "Raw"-version mit voller Präzision und ohne Umrechnung, ähnlich dem Ansatz mit GetAnalogValue().

 

public double GetIlluminanceScaleFactor()

3.Option: Die Bindings bieten wenigstens eine Möglichkeit an zu erfahren mit welchem Scale-Faktor der aktuelle Wert arbeitet.

 

Weiterer Mini-Vorteil: Die bisher nur im Fließtext zu erfahrende Skalierung könnte ebenfalls automatisiert Dokumentiert werden ^^

Link to comment
Share on other sites

@AuronX:

public int GetIlluminance()

public double GetIlluminance(bool scale)

public double GetScaledIlluminance()

{

  return ((double)GetIlluminance() / (double)GetIlluminanceScaleFactor());

}

public int GetIlluminanceScaleFactor()

 

So könnte ich damit leben. Immer die passenden Datentypen wählen...

Aber ist double oder float sinvoll?

Mir sind ints lieber darauf kann ich casten wie ich will. ;-)

Link to comment
Share on other sites

Ints sind schon ziemlich praktisch, obwohl ich das mit dem Parsen nicht verstanden habe ^^

 

Wegen Float vs. Double: Ich denke Float sollte eigentlich überall reichen, da ja die Werte nie in nem Grenzbereich sind (also sehr groß oder sehr viele nachkomma-stellen).

 

Mein double in den Beispielen war jetzt eher Gewohnheit :D

 

P.S.: Die Variante die nen bool als Parameter kriegt finde ich komisch... wenn ich da false übergebe habe ich ja das schlechte beider Welten: Ich muss Dividieren und halte keinen int in der Hand...

Link to comment
Share on other sites

@AuronX: Parsen habe ich jetzt auch nicht verstanden wenn man dort casten schreibt machts plötzlich mehr Sinn. Hörte mit 'ten auf *close enough* ;-P Man sollte immer nur einen Post nach den anderen schreiben. Frage ist wo man mit den Werten "hin will" die .Net Framework Math Klasse verwendet double und die XNA Framework MathHelper Klasse verwendet float...

Link to comment
Share on other sites

Double ist wohl mittlerweile der Standardweg, ausser vielleicht auf embedded. Ein Beispiel für Probleme ist z.B. auf ein Single Precision Float kann man auf Zahlen größer ~16384 nicht mehr 0,0005 aufaddieren (Zeitwert des jeweiligen Samples in Sekunden bei einer Samplingrate von 2kHz). Hat mich mal bei einer kumulativen Zeitinformation für Messwerte erwischt :-[

Link to comment
Share on other sites

Wie gesagt, ich möchte die Übertragung überhaupt nciht ändern, nur das was die Bindings ausgeben. Und das auch eigentlich nur Optional, weil es ja schon sinnvoll ist nicht ins Gleitkomma-Milieu abzurutschen wenn man doch auf maximale Präzision angewiesen ist.

 

Für einen Haufen EInsatzzwecke ist es aber einfach umständlich immer "per Hand" umzurechnen.

Link to comment
Share on other sites

mit float kann ich 0.3 Lux z.B. nicht darstellen, d.h. ich kann z.B. auch nicht testen ob ich bei 1000 Messungen im Schnitt absolut 3 Lux hatte:

 

>>> x = 0
>>> for i in range(1000):
...  x += 3/10.0
... 
>>> x == 300.0
False

 

Da müsste ich jetzt wieder anfangen mit:

if x < 300.0 + epsilon and x > 300.0 - epsilon

 

Warum würde ich das vorziehen wollen?

Link to comment
Share on other sites

@Borg: Deswegen habe ich ja jederzeit das Hintertürchen offen gelassen, dass man int haben kann wenn es auf 100% Präzision ankommt. Aber Holy hat halt recht, dass schon alleine durch die Messungenauigkeit jegliche Vergleiche mit == halbwegs unsinnig sind.

 

Ich behaupte noch immer ganz dreist, dass in 99% der Anwendungsfälle die float-genauigkeit ausreicht und dort eine bequeme Programmierung den Verlust rechtfertigt.

 

Ich finde es btw. auch Klasse, dass ihr euch schon Gedanken gemacht habt, dass eben nicht mal eben fix alles nach Gleitkomma gewandelt wird. Vielerorts wird dieses Problem auch gerne weg-ignoriert.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...