Durchsuche Beiträge, die in der Kategorie August, 2008 erstellt wurden

Wie bereits vor einigen Tagen angedroht, habe ich mittlerweile den NXT geflasht und damit LeJOS als Betriebssystem aufgespielt. Als Grundlage diente mir das ausführliche Tutorial von Christoph Bartneck. Da es mir jedoch nicht gelungen ist, den NXT per USB an den Mac anzuschließen und zudem das Programm zum Flashen nur als Windows-Konsolenanwendung vorliegt, mußte eine Windows-Installation herhalten. Das war dann auch gleich der Härtetest für die Sun xVM VirtualBox, in der Windows XP bei mir läuft. Und ich muß sagen: Es hat funktioniert.

Notwendige Software

Folgende Schritte müssen nun also ausgeführt werden, um die Standard-Firmware des NXT durch LeJOS zu ersetzen:

Schritt 1: Installation der Software

Sofern noch nicht vorhanden, wird als erstes das Java Development Kit installiert. Danach folgt der Mindstorms USB-Treiber. Nun kann der NXT das erste Mal an den Rechner angeschlossen werden und sollte auch im Gerätemanager unter “Lego Devices” auftauchen.
LeJOS wird nun in ein beliebiges Verzeichnis entpackt. Die meisten Tools der Distribution benötigen eine Umgebungsvariable NXJ_HOME, die auf das LeJOS-Verzeichnis verweist. Diese muß entweder im System eingestellt oder vor jeder Verwendung manuell gesetzt werden.
Um über USB auf den NXT zugreifen zu können, wird noch libusb benötigt. Diese Bibliothek kann man entweder über obige Webseite beziehen oder aus dem Verzeichnis 3rdparty/lib der LeJOS-Distribution nehmen. Führt man nach der Installation testlibusb an der Eingabeaufforderung aus, so erscheint der NXT in der Liste der verfügbaren Geräte.

Schritt 2: Den NXT in den Update-Modus versetzen

Über einen kleinen Schalter am Gerät kann der NXT in den Update-Modus versetzt werden. Dieser befindet sich an der Unterseite des Gerätes unter dem USB-Anschluß und ist am besten mit einem langen, spitzen Gegenstand erreichbar. Nach etwa viersekündigem Drücken des Schalters beginnt der NXT, ein regelmäßiges Klick-Geräusch von sich zu geben; dies zeigt den Update-Modus an. Wirft man einen Blick in den Gerätemanager, so verändert sich die Beschreibung dort auch in “Lego Mindstorms NXT Firmware Update Mode”.

Schritt 3: Firmware aufspielen

Nun kann an der Eingabeaufforderung nxjflash.exe aus dem bin-Verzeichnis der LeJOS-Distribution ausgeführt werden. Der Flash-Vorgang dauert nur wenige Sekunden. Das Gerät startet anschließend automatisch neu und präsentiert sich mit neuer Firmware und Benutzerführung.

Heute fand das Sommerfest der hiesigen Niederlassung meines Arbeitgebers statt. Als Veranstaltungsort wurde dieses mal der Nordpark in Düsseldorf gewählt. Ich habe die Gelegenheit sogleich genutzt, mir den Park – insbesondere den Japanischen Garten – anzusehen. Das Wetter hat zum Glück mitgespielt und so habe ich natürlich auch wieder ein paar Bilder gemacht. Die Ergebnisse gibt es wie immer in der Galerie zu bestaunen.

Am heutigen Sonntag war ich mal wieder mit den Öffentlichen hier in Düsseldorf unterwegs und mir ist zum wiederholten Male Folgendes aufgefallen: Bei Fahrkarten, die zu entwerten sind, weicht die vom Entwerter aufgedruckte Zeit stark von der aktuellen ab. Natürlich in die für den Kunden nachteilige Richtung… So wird einem praktisch kostbare Fahrzeit weggenommen – wo die einfachen Fahrkarten schon nur 90 Minuten gültig sind. In meinem Fall wich die Zeit heute sage und schreibe acht Minuten ab, was 10% verkürzte Fahrzeit zur Folge hat.
Meine Frage: Ist das Absicht oder sind die zu blöd, die Entwerter vernünftig einzustellen?

Achso, und wo wir gerade beim Thema sind: Die zehn Prozent verkürzte Fahrzeit wurden Anfang dieses Monats sozusagen auf den Fahrpreis aufgeschlagen. Ganz stolz verkündete der hiesige Verkehrsverbund neue Tarifzonen und hat das gleich zum Anlaß für eine Erhöhung der Fahrpreise genutzt…

Klein-Olli hat sich heute ein neues Spielzeug zugelegt: Seinen ersten Lego-Baukasten in Form eines Lego Mindstorms NXT. Riesenkarton mt einem Haufen Tüten und viel Luft darin. Mit dabei auch eine Anleitung, die einen ersten Roboter in 30 Minuten verspricht. Naja, hab ich nicht ganz geschafft, bei mir waren es etwa 45 Minuten, bis er komplett war. Aber schön zu sehen, daß die Demonstration der Fähigkeiten funktioniert hat: Der Roboter fährt im Demomodus ein wenig hinundher und macht Geräusche.

In nächster Zeit werde ich also mit dem NXT experimentieren. Dazu wird einer der ersten Schritte sein, den Baustein zu flashen und mit LeJOS auszurüsten. Dann muß ich nicht noch eine Sprache lernen oder gar mit C rumhantieren. Meine Erfahrungen und Ergebnisse werde ich sicher auch ab und zu hier präsentieren.

Vor kurzem bin ich auf Arbeit über folgendes Problem gestolpert: Gegeben sei ein Wert x, der in eine Menge von Werten xn aufgeteilt werden soll. Das Verhältnis der Verteilung soll dabei der Verteilung einer bekannten Menge von Werten yn mit der Summe y entsprechen. Die ersten Versuche mit Dreisatz und Verhältnisgleichungen führten allerdings nicht zum gewünschten Ergebnis. Da Werte gerundet wurden und die Divisionen durchaus Werte mit unendlichen Nachkommmastellen ergaben, traten bereits bei kleineren Beträgen Fehler auf.
Nach kurzer Diskussion wurde ich auf einen Algorithmus von Martin Fowler zur Allokation von Geldwerten aufmerksam gemacht. Dieser ermöglicht die restfreie Aufteilung eines gegebenen Betrags. Mit diesem Algorithmus kann man “Foemmel’s Conundrum” lösen, welches versucht, 5 Cent in einem 30/70-Verhältnis zu verteilen (Lösung: 2 Cent/3 Cent).
Fowler arbeitet in seinem Beispiel mit ganzzahligen Werten vom primitiven Typ long. Es ist jedoch zu beachten, daß dies bei großen Werten durchaus zu Überläufen und damit falschen Ergebnissen (oder gar Ausnahmen…) führen kann. Ich habe daher den Algorithmus für Java so angepaßt, daß er mit java.math.BigInteger rechnet, womit Überläufe ausgeschlossen sind. Und so sieht das ganze dann aus:

private static BigInteger[] allocate(BigInteger amount, BigInteger[] ratios) {
    BigInteger total = BigInteger.ZERO;
    for(int i=0; i<ratios.length; i++) {
        total = total.add(ratios[i]);
    }
    BigInteger remainder = amount;
    BigInteger[] results = new BigInteger[ratios.length];
    for(int i=0; i<ratios.length; i++) {
        results[i] = amount.multiply(ratios[i]).divide(total);
        remainder = remainder.subtract(results[i]);
    }
    for(int i=0; i<remainder.intValue(); i++) {
        results[i] = results[i].add(BigInteger.ONE);
    }
    return results;
}

Bleibt nun die Frage, wie uns dieser Algorithmus bei nicht-ganzzahligen Werten hilft. Nun, nehmen wir an, wir haben eine Menge von java.math.BigDecimal-Werten. Dann müssen diese in eine ganzzahlige Form gebracht werden. Zunächst müssen alle Werte auf die gleiche Anzahl Nachkommastellen gerundet werden; damit bleiben die Zahlenverhältnisse in der ganzzahligen Form erhalten. Da java.math.BigDecimal intern bereits einen ganzzahligen Wert zusammen mit einer Skalierung (Anzahl Nachkommastellen) speichert, ist die Umwandlung kein Problem. Die so berechneten Werte dienen nun als Eingabe für den gezeigten Algorithmus. Die Werte in der Ergebnismenge sollten im letzten Schritt auf die Anzahl Nachkommastellen des zu verteilenden Wertes gerundet werden, jede andere Anzahl Stellen ergibt keinen Sinn. Man kann z.B. nur ganzzahlige Centbeträge verteilen und diese in den Verteilungen wiederfinden. Damit sieht die Verteilung beliebiger Werte wie folgt aus:

private static BigDecimal[] allocate(BigDecimal _amount, 
        BigDecimal[] _ratios) {
    // max. Anzahl NKS aus allen beteiligten Werten ermitteln
    int maxScale = _amount.scale();
    for(int i=0; i<_ratios.length; i++) {
        if (_ratios[i].scale() > maxScale) 
            maxScale = _ratios[i].scale();
    }
    // nun alle _ratios neu skalieren und dabei in Ganzzahlen umwandeln
    BigInteger[] ratios = new BigInteger[_ratios.length];
    for(int i=0; i<_ratios.length; i++) {
        ratios[i] = _ratios[i].setScale(maxScale, 
                BigDecimal.ROUND_HALF_UP).unscaledValue();
    }
    // den Eingangswert neu skalieren und in Ganzzahl umwandeln
    BigInteger amount = _amount.setScale(maxScale, 
            BigDecimal.ROUND_HALF_UP).unscaledValue();
 
    // den Algorithmus ausführen
    BigInteger[] results = allocate(amount, ratios);
 
    // nun die Ergebnisse wieder in umwandeln
    // Anzahl NKS ist gleich der des Eingangswertes
    BigDecimal[] _results = new BigDecimal[results.length];
    for(int i=0; i<results.length; i++) {
        _results[i] = new BigDecimal(results[i], maxScale).setScale(
                                _amount.scale(), BigDecimal.ROUND_HALF_UP);
    }
    return _results;
}
Powered by WordPress Web Design by SRS Solutions © 2010 artanis.info Design by SRS Solutions