Graphics2D representation of sensor readings

Post your EV3 projects, project ideas, etc here!

Moderators: roger, gloomyandy, skoehler

Graphics2D representation of sensor readings

Postby steveiswicked » Mon Oct 28, 2013 10:36 pm

Hello, Im trying to write a java app that graphically represents sensor readings on a PC in real time. I've written/hacked a UDP client for EV3 that sends a serialized object containing a sensor reading and a UDP server that receives and acknowledges it. But I am really baffled by AWT/SWT/SWING, I cannot work out a way of passing the newly received value to a graphical object will update each time its received. I realise this is more a question about Java programming than about EV3 but I cant find any simple examples of a technique to help me do it. Help would be much appreciated.

Regards
Steve

Here's my UDP Server code

Code: Select all
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UDPSocketServer {

    DatagramSocket socket = null;
    String passText;
 
    public UDPSocketServer() {
    }

    public void createAndListenSocket() {
        try {
            socket = new DatagramSocket(9876);
            byte[] incomingData = new byte[1024];

            while (true) {
                DatagramPacket incomingPacket = new DatagramPacket(incomingData, incomingData.length);
                socket.receive(incomingPacket);
                byte[] data = incomingPacket.getData();
                ByteArrayInputStream in = new ByteArrayInputStream(data);
                ObjectInputStream is = new ObjectInputStream(in);
                try {
                    SensorMessage sensorMessage = (SensorMessage) is.readObject();
                    System.out.println("Sensor object received = " + sensorMessage);
                    passText=sensorMessage.getAddressLine();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }

                InetAddress IPAddress = incomingPacket.getAddress();
                int port = incomingPacket.getPort();
                String reply = " Ack "+ passText +" message";
                byte[] replyBytea = reply.getBytes();
                DatagramPacket replyPacket =
                        new DatagramPacket(replyBytea, replyBytea.length, IPAddress, port);
                socket.send(replyPacket);
//                System.exit(0);
            }

        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException i) {
            i.printStackTrace();
        }
    }

    public static void main(String[] args) {
        UDPSocketServer server = new UDPSocketServer();
        server.createAndListenSocket();
    }
}


Here's my serialized object

Code: Select all
import java.io.Serializable;

public class SensorMessage implements Serializable {

    private static final long serialVersionUID = 1L;
    private int id;
    private String name;
    private String addressLine;   
    private float value;

   public SensorMessage(int id, String name, String address1, float value) {
        this.id = id;
        this.name = name;
        this.addressLine = address1;
        this.value = value;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddressLine() {
        return addressLine;
    }

    public void setAddressLine(String addressLine) {
        this.addressLine = addressLine;
    }

    public float getValue() {
        return value;
    }

    public void setValue(float value) {
        this.value = value;
    }
   
    public String toString() {
        return "Id = " + getId() + " Name = " + getName() + " Address = " + getAddressLine()
              + " Value = " + getValue();
    }

}
steveiswicked
New User
 
Posts: 19
Joined: Sun Feb 06, 2011 11:22 pm

Re: Graphics2D representation of sensor readings

Postby cfin » Thu Oct 31, 2013 6:18 pm

Hello,
perhaps you want to take a look at graphite (http://graphite.wikidot.com/screen-shots).
You set up the server and then send the measurement data from the robot to that server via udp or http-call (http://docs.hostedgraphite.com/).

You then have a graphical web interface to see your data graphs. We use that tool at work and we like it.
It is opensource, so no additional costs.
cfin
New User
 
Posts: 15
Joined: Fri Oct 25, 2013 8:04 pm

Re: Graphics2D representation of sensor readings

Postby skoehler » Thu Oct 31, 2013 8:27 pm

leJOS NXJ included the charting logger tool. It uses the JFreeChart swing component for drawing things, afaik.
skoehler
leJOS Team Member
 
Posts: 1350
Joined: Thu Oct 30, 2008 4:54 pm

Re: Graphics2D representation of sensor readings

Postby steveiswicked » Thu Oct 31, 2013 11:34 pm

Thanks for the tips. I've turned my udp server into a thread. It stores the latest sensor data into an array based on the id passed in the SensorMessage class and now I can access the array from within the graphics program using...
Code: Select all
       if (server == null) {
       server = new UDPSocketServer2();
      server.start();
       }

The new server code...
Code: Select all
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UDPSocketServer2 extends Thread{

    DatagramSocket socket = null;
    String passText;
    private static float[] value = {0F,0F,0F,0F,0F,0F,0F,0F,0F,0F,0F};
 
    public UDPSocketServer2() {

    }

    public void createAndListenSocket() {
        try {
            socket = new DatagramSocket(9876);
            byte[] incomingData = new byte[1024];

            while (true) {
                DatagramPacket incomingPacket = new DatagramPacket(incomingData, incomingData.length);
                socket.receive(incomingPacket);
                byte[] data = incomingPacket.getData();
                ByteArrayInputStream in = new ByteArrayInputStream(data);
                ObjectInputStream is = new ObjectInputStream(in);
                try {
                    SensorMessage sensorMessage = (SensorMessage) is.readObject();
                    System.out.println("Sensor object received = " + sensorMessage);
                    setValue(sensorMessage);
                    passText=sensorMessage.getAddressLine();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }

                InetAddress IPAddress = incomingPacket.getAddress();
                int port = incomingPacket.getPort();
                String reply = " Ack "+ passText +" message";
                byte[] replyBytea = reply.getBytes();
                DatagramPacket replyPacket =
                        new DatagramPacket(replyBytea, replyBytea.length, IPAddress, port);
                socket.send(replyPacket);
            }

        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException i) {
            i.printStackTrace();
        }
    }
   
    public void setValue(SensorMessage x) {
       value[x.getId()]= x.getValue();
    }
   
    public float getValue(int index) {
       return value[index];
    }

    public static void main(String[] args) {

    }

   @Override
   public void run() {
      // TODO Auto-generated method stub
         UDPSocketServer2 server = new UDPSocketServer2();
           server.createAndListenSocket();
   }
}

The new sensorMessage class which still needs tidying up...
Code: Select all
import java.io.Serializable;

public class SensorMessage implements Serializable {

    private static final long serialVersionUID = 1L;
    private int id;
    private String deviceName;
    private String sensorName;   
    private float value;

   public SensorMessage(int id, String name, String address1, float value) {
        this.id = id;
        this.deviceName = name;
        this.sensorName = address1;
        this.value = value;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return deviceName;
    }

    public void setName(String name) {
        this.deviceName = name;
    }

    public String getAddressLine() {
        return sensorName;
    }

    public void setAddressLine(String addressLine) {
        this.sensorName = addressLine;
    }

    public float getValue() {
        return value;
    }

    public void setValue(float value) {
        this.value = value;
    }
   
    public String toString() {
        return "Id = " + getId() + " Device Name = " + getName() + " Sensor Name = " + getAddressLine()
              + " Value = " + getValue();
    }

}

This all miight be redundant because it looks like the Lejos team are working on Remote Method Invocation for the next release and we'll be able to access the sensors directly from the remote application, but for the record here's my UDP test client.

Code: Select all
import java.net.*;

import lejos.nxt.Button;
import lejos.nxt.ADSensorPort;
import lejos.nxt.SensorPort;
import lejos.nxt.UARTPort;
import lejos.nxt.I2CPort;
import lejos.nxt.addon.CompassMindSensor;
import lejos.nxt.EV3IRSensor;
import lejos.nxt.addon.GyroSensor;
import lejos.nxt.UltrasonicSensor;
import lejos.nxt.Motor;

public class TestSendSensorMessage {

    DatagramSocket Socket;
    static String destination = "legolass";
    static SendSensorMessage sSM1;
    static SendSensorMessage sSM2;
    static SendSensorMessage sSM3;
    static SendSensorMessage sSM4;
    static SendSensorMessage sSM5;
   
    public TestSendSensorMessage() {

    }

    public static void main(String[] args) throws InterruptedException {
 
       UltrasonicSensor uSensor = new UltrasonicSensor((I2CPort) SensorPort.S1);
       uSensor.continuous();
       CompassMindSensor compass = new CompassMindSensor((I2CPort)SensorPort.S2, 2);
       EV3IRSensor iRSensor = new EV3IRSensor((UARTPort)SensorPort.S3);
       GyroSensor gyroSensor = new GyroSensor((ADSensorPort)SensorPort.S4);

       
       while (!Button.ESCAPE.isDown()) {
   
        sSM1 = new SendSensorMessage(new SensorMessage
             (1, "EV3", "Compass",compass.getDegrees()),destination);
       
        sSM2= new SendSensorMessage(new SensorMessage
             (2, "EV3", "EV3IRSensor",iRSensor.getRange()),destination);
       
        sSM3 = new SendSensorMessage(new SensorMessage
             (3, "EV3", "GyroSensor",gyroSensor.getAngularVelocity()),destination);
       
        sSM4 = new SendSensorMessage(new SensorMessage
              (4, "EV3", "UltrasonicSensor",uSensor.getRange()),destination);

        sSM5 = new SendSensorMessage(new SensorMessage
               (5, "EV3", "MotorA",Motor.A.getTachoCount()),destination);
       
        sSM5 = new SendSensorMessage(new SensorMessage
                (6, "EV3", "MotorB",Motor.B.getTachoCount()),destination);
         
       }

    }

}
steveiswicked
New User
 
Posts: 19
Joined: Sun Feb 06, 2011 11:22 pm

Re: Graphics2D representation of sensor readings

Postby kirkpthompson » Mon Dec 16, 2013 2:44 pm

Hi.

There is ongoing work being done on the NXJChartingLogger to get it ready to use with the EV3. This includes TCP socket connection manager and 2 newly supported chart types in addition to the existing time series line chart: XY scatter and XYZ bubble.

Stay tuned..

Best,
-K
Leg Godt!
User avatar
kirkpthompson
leJOS Team Member
 
Posts: 304
Joined: Wed Dec 05, 2007 1:27 am
Location: New Mexico, USA


Return to EV3 Projects

Who is online

Users browsing this forum: No registered users and 0 guests

more stuff