jawedoo Geschrieben December 13, 2017 at 13:24 Geschrieben December 13, 2017 at 13:24 Hallo liebe Leute, Ich hab hier an einem Red-Brick eine IMU 2.0, einen Accelerometer und ein GPS bricklet. jetzt würde ich gerne zu einer bestimmten Frequenz (20Hz z.b.) von allen Sensoren ihre aktuellen Daten bekommen. Geht das auf diese Art und Weise?: Alldata-Listener der Imu ruft eine außenstehende methode auf und übergibt alle 3 sensoren. Diese werden ausgelesen und geloggt. Mein gedanke war, dass ich nur den Alldata callback von der IMU nutze, weil diese sich mit sicherheit ändert und auf die 20Hz hört (alle anderen callbacks auch einzuschalten würde meine logdatenzahl vervielfachen und nicht zum gewünschten effekt führen)... nur ist mein problem dass ich statt 20 ergebnissen pro sekunde z.b. nur 13/15 bekomme... die imu unterstütz ja eigentlich eine Abtastrate von 100Hz, übersehe ich da was? Hier mein Code, bin für jede Hilfe dankbar =) public class Red { private static final String HOST = "localhost"; private static final int PORT = 4223; private static final String UID = "xxx"; //IMUV2 private static final String UID2 = "xx2"; //Accelerometer 1.1 private static final String UID3 = "xx3"; //GPS 1.0 private static final int HERZ = 20; //Set here your desired Frequency public static void main(String args[]) throws Exception { IPConnection ipcon = new IPConnection(); // Create IP connection BrickIMUV2 imu = new BrickIMUV2(UID, ipcon); BrickletAccelerometer accel = new BrickletAccelerometer(UID2, ipcon); BrickletGPS gps = new BrickletGPS(UID3, ipcon); ipcon.connect(HOST, PORT); // Connect to brickd // Don't use device before ipcon is connected //#####################All Listeners are going to trigger the logging###################### // Add all data listener imu.addAllDataListener(new BrickIMUV2.AllDataListener() { public void allData(short[] acceleration, short[] magneticField, short[] angularVelocity, short[] eulerAngle, short[] quaternion, short[] linearAcceleration, short[] gravityVector, byte temperature, short calibrationStatus) { output(imu, accel, gps); } }); //###############################Listener Ends here ####################################### // Set period for all callbacks imu.setAllDataPeriod(1000/HERZ); //first line for titles System.out.println("Euler Angle x;ImuAccel x;ImuAccel y; Accel x; Accel y;Latitude;Longitude;Speed;Date;Time;Satelites used;GPS fix"); System.in.read(); ipcon.disconnect(); } private static void output(BrickIMUV2 imu, BrickletAccelerometer accel, BrickletGPS gps){ try { LinearAcceleration acc = imu.getLinearAcceleration(); Acceleration acc2 = accel.getAcceleration(); Orientation euler = imu.getOrientation(); Coordinates coords = gps.getCoordinates(); Motion speed = gps.getMotion(); Status stat = gps.getStatus(); String timeStamp = new SimpleDateFormat("dd.MM.yyyy;HH:mm:ss.SSS").format(new Date()); System.out.println(euler.heading/16 + ";" + acc.x/100.0 + ";" + acc.y/100.0 + ";" + acc2.x/1000.0 + ";" + acc2.y/1000.0 + ";" + coords.latitude/1000000.0 + ";" + coords.longitude/1000000.0 + ";" + speed.speed/100.0 + ";" + timeStamp + ";" + stat.satellitesUsed + ";" + stat.fix); } catch (TimeoutException | NotConnectedException e) { // dont log } } } Zitieren
bernhard.graeuler Geschrieben January 20, 2018 at 22:42 Geschrieben January 20, 2018 at 22:42 Hi, Du stellst Dir gleich zweimal ein Bein: Du verwendest den Callback der IMU als Scheduler für Deine Anwendung.Statt die Werte, die die IMU im Callback schon liefert rufst Du sie lieber noch mal neu ab. (short[] acceleration im Callback vs. imu.getLinearAcceleration() in output(...)) Ich würde (für quick & dirty) empfehlen die Werte, die Du im AllDataListener::allData([viele Arrays]) bekommst, in ein ImuData POJO zu verpacken in output(imudata, accel, gps) zu übergeben, und noch zusätzlich die anderen Brick(let)s abzurufen. Eine gute Lösung wäre meiner Meinung nach, für alle benötigten Datenquellen periodic Callback Listener zu registrieren, damit die Werte periodisch schicken zu lassen und in einer ConcurrentHashMap zu speichern. In einem separaten Task kannst Du die Werte dann periodisch aus der Map lesen und ausgeben. Wenn es unbedingt Polling sein soll, verwende besser einen ScheduledTaskExecutor. Dann ersparst Du dem Datenbus wenigstens die Last, Dir alle IMU Werte doppelt zu schicken (1x Callback + 1x getNNN() im Output). Freundliche Grüße Bernhard Zitieren
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.