package com.roboclub.robobuggy.ui; import Jama.Matrix; import com.roboclub.robobuggy.messages.BatteryLevelMessage; import com.roboclub.robobuggy.messages.BrakeStateMessage; import com.roboclub.robobuggy.messages.FingerPrintMessage; import com.roboclub.robobuggy.messages.GpsMeasurement; import com.roboclub.robobuggy.messages.IMUAngularPositionMessage; import com.roboclub.robobuggy.ros.NodeChannel; import com.roboclub.robobuggy.ros.Subscriber; import javax.imageio.ImageIO; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; /** * Created by vivaanbahl on 4/1/16. */ public class BuggyStatusPanel extends RobobuggyGUIContainer { private boolean brakesDown; private int batteryLevel; private String fphash = "(not loaded yet)"; private BufferedImage imuArrow; private BufferedImage gpsArrow; private double imuAngle; private double gpsAngle; private GpsMeasurement prevGPS; /** * initializes a new Buggy status panel */ public BuggyStatusPanel() { setupDataLoaders(); try { imuArrow = ImageIO.read(new File("images/imuarrow.jpg")); imuArrow = toBufferedImage(imuArrow.getScaledInstance(150, 50, 0)); gpsArrow = ImageIO.read(new File("images/gpsarrow.jpg")); gpsArrow = toBufferedImage(gpsArrow.getScaledInstance(150, 50, 0)); } catch (IOException e) { e.printStackTrace(); } // this.addComponent(new ImageViewer(NodeChannel.PUSHBAR_CAMERA.getMsgPath()), .75, 0, .25, 1.0); } private void setupDataLoaders() { new Subscriber("uiStatus", NodeChannel.BRAKE_STATE.getMsgPath(), (topicName, m) -> { brakesDown = ((BrakeStateMessage) m).isDown(); }); new Subscriber("uiStatus", NodeChannel.BATTERY.getMsgPath(), (topicName, m) -> { batteryLevel = ((BatteryLevelMessage) m).getBatteryLevel(); }); new Subscriber("uiStatus", NodeChannel.FP_HASH.getMsgPath(), (topicName, m) -> { fphash = String.format("%x", ((FingerPrintMessage) m).getFpHash()); }); new Subscriber("buggyStatusPanel", NodeChannel.IMU_ANG_POS.getMsgPath(), ((topicName, m) -> { IMUAngularPositionMessage mes = ((IMUAngularPositionMessage) m); Matrix r = new Matrix(mes.getRot()); double[][] xVec = { { 1 }, { 0 }, { 0 } }; double[][] yVec = { { 0 }, { 1 }, { 0 } }; double x = r.times(new Matrix(xVec)).get(0, 0); double y = r.times(new Matrix(yVec)).get(0, 0); imuAngle = Math.atan2(y, x); repaint(); })); new Subscriber("buggyStatusPanel", NodeChannel.GPS.getMsgPath(), ((topicName, m) -> { if (prevGPS == null) { prevGPS = ((GpsMeasurement) m); } else { GpsMeasurement gps = ((GpsMeasurement) m); double dlat = gps.getLatitude() - prevGPS.getLatitude(); double dlon = gps.getLongitude() - prevGPS.getLongitude(); gpsAngle = -Math.atan2(dlat, dlon); } })); } private static BufferedImage toBufferedImage(Image img) { if (img instanceof BufferedImage) { return (BufferedImage) img; } // Create a buffered image with transparency BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); // Draw the image on to the buffered image Graphics2D bGr = bimage.createGraphics(); bGr.drawImage(img, 0, 0, null); bGr.dispose(); // Return the buffered image return bimage; } @Override protected void paintComponent(Graphics f) { super.paintComponent(f); int brakeX = 50; int brakeY = 0; String status = "up"; int battLevelBoxLeft = brakeX + getHeight(); if (brakesDown) { brakeY = getHeight() - getHeight() / 3; status = "down"; } Graphics2D g = (Graphics2D) f; g.setColor(Color.RED); g.fillOval(brakeX, brakeY, getHeight() / 3, getHeight() / 3); g.setColor(Color.GREEN); g.fillRect(battLevelBoxLeft, 0, getHeight() / 3, getHeight()); g.setColor(Color.BLACK); g.setFont(new Font("Arial", Font.BOLD, 30)); g.drawString("batt = " + batteryLevel, battLevelBoxLeft, getHeight() / 2); g.drawString("status = " + status, 0, getHeight() / 2); g.drawString("fphash = " + fphash, battLevelBoxLeft, 30); // shamelessly ripped from stackoverflow g.drawImage(imuArrow, new AffineTransform(Math.cos(imuAngle), Math.sin(imuAngle), -Math.sin(imuAngle), Math.cos(imuAngle), 500, 200), null); g.drawImage(gpsArrow, new AffineTransform(Math.cos(gpsAngle), Math.sin(gpsAngle), -Math.sin(gpsAngle), Math.cos(gpsAngle), 700, 100), null); } }