/**
*
* @author greg (at) myrobotlab.org
*
* This file is part of MyRobotLab (http://myrobotlab.org).
*
* MyRobotLab is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 2 of the License, or (at your option) any later
* version (subject to the "Classpath" exception as provided in the LICENSE.txt
* file that accompanied this code).
*
* MyRobotLab is distributed in the hope that it will be useful or fun, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* All libraries in thirdParty bundle are subject to their own license
* requirements - please refer to http://myrobotlab.org/libraries for details.
*
* Enjoy !
*
*
*/
package org.myrobotlab.control;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JList;
import javax.swing.JTabbedPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.myrobotlab.image.SerializableImage;
import org.myrobotlab.logging.LoggerFactory;
import org.myrobotlab.service.GUIService;
import org.myrobotlab.service.interfaces.VideoGUISource;
import org.slf4j.Logger;
public class LIDARGUI extends ServiceGUI implements ListSelectionListener, VideoGUISource {
static final long serialVersionUID = 1L;
public final static Logger log = LoggerFactory.getLogger(LIDARGUI.class.toString());
VideoWidget screen = null;
Graphics cam = null;
Graphics graph = null;
BufferedImage camImage = null;
BufferedImage graphImage = null;
int width = 1536;
int height = 768;
int xyScale = 2;
ArrayList<ArrayList<Integer>> history = new ArrayList<ArrayList<Integer>>(); // A
// list
// of
// lists
// for
// holding
// old
// data
public Random rand = new Random();
int vheight = height / xyScale;
int vwidth = width / xyScale;
ArrayList<Integer> hist = new ArrayList<Integer>();
boolean staticInfo = false;
DecimalFormat df = new DecimalFormat("#.##");
int cnt = 0;
public LIDARGUI(final String boundServiceName, final GUIService myService, final JTabbedPane tabs) {
super(boundServiceName, myService, tabs);
}
@Override
public void attachGUI() {
subscribe("publishLidarData", "displaySweepData", int[].class);
}
protected ImageIcon createImageIcon(String path, String description) {
java.net.URL imgURL = getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL, description);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
@Override
public void detachGUI() {
unsubscribe("publishLidarData", "displaySweepData", int[].class);
}
public void displayFrame(SerializableImage camImage) {
screen.displayFrame(camImage);
}
// TODO - check for copy/ref of parameter moved locally
// TODO remove IREven
// find angle
public void displaySweepData(int[] points) {
int[] x = new int[points.length]; // Just initializing them to the
// correct size, values will be
// overwritten below
int[] y = new int[points.length];
// int zScale = 8; // 11
// int xOffset = vwidth / 2; // set origin of polar in middle
if (points != null) {
// blank screen
graph.setColor(Color.black);
graph.fillRect(0, 0, vwidth, vheight);
// draw static parts
// Draw Crosshairs
graph.setColor(Color.gray);
// int midh = (vheight) / 2;
int midw = (vwidth) / 2;
graph.drawLine(midw - 20, vheight - 2, midw + 20, vheight - 2);
graph.drawLine(midw, vheight, midw, vheight - 30);
for (int i = 0; i < vheight; i += 60) {
graph.drawLine(0, vheight - i, vwidth, vheight - i);
}
drawStaticInfo(); // draw arcs on the screen
// get the first and last point
// int first = points[0];
graph.setColor(Color.green);
int length = points.length;
float startingAngle = 0;
if (length == 101 || length == 201 || length == 401) {
startingAngle = 40;
}
// int p;
graph.setColor(Color.green);
for (int i = 0; i < length; ++i) {
// polar coordinates !
// x = (int) ((points[i]) * Math.cos(((i * 100 / length) +
// startingAngle) * (3.14159 / 180)) + xOffset);
// y = vheight - (int) ((points[i]) * Math.sin(((i * 100 /
// length) + startingAngle) * (3.14159 / 180))); //vheight
// inverts the Y-coordinates
x[i] = (int) ((points[i]) * Math.cos(((i * 100 / length) + startingAngle) * (3.14159 / 180)));
y[i] = (int) ((points[i]) * Math.sin(((i * 100 / length) + startingAngle) * (3.14159 / 180))); // vheight
// inverts
// the
// Y-coordinates
System.out.println(x[i] + "\t" + y[i]);
}
// map current value to window size. Values will be plotted so
// largest value = 95% of the window size
int[] xMinMax = getMinMax(x); // Get Max and Min values from the
// array
int[] yMinMax = getMinMax(y); // Get Max and Min values from the
// array
System.out.println("xMin= " + xMinMax[0] + " xmax= " + xMinMax[1] + " ymin= " + yMinMax[0] + " ymax= " + yMinMax[1]);
for (int i = 0; i < length; ++i) {
// scales the screen so that the values fit within 95% of the X
// and Y values
// x[i] = map(x[i], 100, xMax - 100, 0, (int) (vwidth *
// 0.95))+xOffset/2 ;
// y[i] = map(y[i], 100, yMax - 100, 0, (int) (vheight * 0.95));
/*
* Scales y to 8 meters high and X to 8 meters in each direction the Max
* distance of a LMS200 and X to
*/
x[i] = map(x[i], xMinMax[0], xMinMax[1], 0, vwidth - 5);
y[i] = vheight - map(y[i], 0, yMinMax[1], 0, vheight - 5); // the
// "vheight -"
// inverts
// the
// data
// for
// display
// in
// the
// window
System.out.println(x[i] + "\t" + y[i]);
// graph.drawLine(x[i], y[i], x[i], y[i]);//draws a dot on the
// point
if (i > 0) {
graph.drawLine(x[i - 1], y[i - 1], x[i], y[i]);// draws an
// actual
// line from
// point to
// point
}
}
// draw history TODO - draw history first
/*
* history = (dir.compareTo(leftstr)==0)?left:right;
*/
int v = 180;
for (int i = 0; i < history.size(); ++i) {
ArrayList<Integer> sweep = history.get(i);
graph.setColor(new Color(v, v, v));
for (int j = sweep.size(); j > 0; j--) {
// p = sweep.get(j);
// // x = vwidth - ((int) (p *
// Math.cos((i*100/length)+startingAngle) * zScale));
// // y = vheight - ((int) (p *
// Math.sin((i*100/length)+startingAngle) * zScale));
// x = vwidth ((int) (p *
// Math.cos((i*100/length)+startingAngle) *
// zScale)+xOffset);
// y = vheight - ((int) (p *
// Math.sin((i*100/length)+startingAngle) * zScale));
// graph.drawLine(x, y, x, y);
}
v -= 30;
}
int maxHistory = 3;
// history.add(WiiDAR.copy(points));
// p = history.get(0).get(0);
if (history.size() > maxHistory) {
history.remove(0);
}
screen.displayFrame(new SerializableImage(graphImage, boundServiceName));
}
}
public void drawStaticInfo() {
graph.setColor(Color.gray);
// int inches = 0;
// 10 inches per 140 inches
int r = 160;
for (r = 160; r < vheight * 2; r += 160) {
// inches += 10;
graph.drawArc(vwidth / 2 - r / 2, vheight - r / 2, r, r, 0, 180);
// graph.drawLine(0, vheight - i, vwidth, vheight - i);
// graph.drawArc(vwidth - 40, vheight, vheight - i - 5, vheight - i
// - 5, 0, 360);
// graph.drawArc(vwidth - 40, vheight, 30, 30, 0, 360);
// graph.drawArc(vwidth/2 - 100, vheight - 100, 200, 200, 0, 180);
// Print text on the screen
// graph.drawString("" + inches, vwidth / 2 + r / 2, vheight - 10);
}
staticInfo = true;
}
@Override
public VideoWidget getLocalDisplay() {
return screen;
}
public int getMax(int[] points) {
int max; // Values are stored as {min, max}
max = points[0]; // set initial values
for (int i = 1; i < points.length; i++) { // store the highest value
if (points[i] > max) {
max = points[i];
}
} // end for all values
// log.info("Min num = "+minMax[0]+" Max num = "+minMax[1]);
return max;
}
public int[] getMinMax(int[] points) {
int[] minMax = { 0, 0 }; // Values are stored as {min, max}
minMax[0] = points[0]; // set initial values
minMax[1] = points[0];
for (int i = 1; i < points.length; i++) { // store the smallest value
if (points[i] < minMax[0]) {
minMax[0] = points[i];
}
if (points[i] > minMax[1]) { // Store the highest value
minMax[1] = points[i];
}
} // end for all values
// log.info("Min num = "+minMax[0]+" Max num = "+minMax[1]);
return minMax;
}
@Override
public void init() {
screen = new VideoWidget(boundServiceName, myService, tabs);
screen.init();
camImage = new BufferedImage(width / xyScale, height / xyScale, BufferedImage.TYPE_INT_RGB);
graphImage = new BufferedImage(width / xyScale, height / xyScale, BufferedImage.TYPE_INT_RGB);
cam = camImage.getGraphics();
graph = graphImage.getGraphics();
graph.setColor(Color.green);
screen.displayFrame(new SerializableImage(graphImage, boundServiceName));
gc.gridx = 0;
gc.gridy = 0;
gc.gridheight = 4;
gc.gridwidth = 2;
display.add(screen.display, gc);
gc.gridx = 2;
gc.gridx = 0;
gc.gridheight = 1;
gc.gridwidth = 1;
gc.gridy = 5;
setCurrentFilterMouseListener();
}
public int map(int x, int in_min, int in_max, int out_min, int out_max) {
// log.info("mapping "+ x+ " to a min of "+out_min +
// " and a max of "+out_max);
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
// TODO - encapsulate this
// MouseListener mouseListener = new MouseAdapter() {
public void setCurrentFilterMouseListener() {
MouseListener mouseListener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent mouseEvent) {
JList theList = (JList) mouseEvent.getSource();
if (mouseEvent.getClickCount() == 2) {
int index = theList.locationToIndex(mouseEvent.getPoint());
if (index >= 0) {
Object o = theList.getModel().getElementAt(index);
System.out.println("Double-clicked on: " + o.toString());
}
}
}
};
}
@Override
public void valueChanged(ListSelectionEvent arg0) {
}
}