216 lines
6.9 KiB
Java
216 lines
6.9 KiB
Java
import javax.swing.*;
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
import java.net.SocketException;
|
|
import java.net.UnknownHostException;
|
|
import java.util.ArrayList;
|
|
import java.util.Timer;
|
|
import java.util.TimerTask;
|
|
|
|
public class Gui extends JFrame implements KeyListener, MouseWheelListener {
|
|
private VisualPanel visualPanel;
|
|
private JButton zeroButton;
|
|
private JButton averageButton;
|
|
private Robot robot;
|
|
|
|
record Pos(double x, double y){}
|
|
private final ArrayList<Pos> maps = new ArrayList<>();
|
|
|
|
public Gui() throws SocketException, UnknownHostException {
|
|
robot = new Robot();
|
|
|
|
setTitle("Wrobot");
|
|
setSize(1200, 600);
|
|
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
|
setLayout(new BorderLayout());
|
|
|
|
visualPanel = new VisualPanel();
|
|
add(visualPanel, BorderLayout.CENTER);
|
|
|
|
zeroButton = new JButton("Zero");
|
|
zeroButton.addActionListener(e -> {
|
|
robot.sendZero().error(ex -> ex.printStackTrace());
|
|
maps.clear();
|
|
});
|
|
zeroButton.setFocusable(false);
|
|
add(zeroButton, BorderLayout.SOUTH);
|
|
|
|
averageButton = new JButton("Find Average Angle");
|
|
averageButton.addActionListener( e -> averageAngle());
|
|
averageButton.setFocusable(false);
|
|
add(averageButton, BorderLayout.NORTH);
|
|
|
|
|
|
setFocusable(true);
|
|
addKeyListener(this);
|
|
addMouseWheelListener(this);
|
|
add(new PidPanel(robot), BorderLayout.EAST);
|
|
|
|
setVisible(true);
|
|
|
|
new Thread(() -> {
|
|
while(true){
|
|
try{
|
|
visualPanel.updateData(robot.getDataPlus().await(1000));
|
|
}catch (Exception e){
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}).start();
|
|
|
|
}
|
|
|
|
public void averageAngle(){
|
|
new Thread(() -> {
|
|
var sum = 0.0;
|
|
int number = 500;
|
|
for(int i = 0; i < number; i ++){
|
|
try {
|
|
sum += robot.getEverything().await()[17-1];
|
|
} catch (Exception ex) {
|
|
throw new RuntimeException(ex);
|
|
}
|
|
}
|
|
System.out.println(sum/number);
|
|
}).start();
|
|
}
|
|
|
|
|
|
@Override
|
|
public void keyPressed(KeyEvent e) {
|
|
int key = e.getKeyCode();
|
|
float panStep = 20;
|
|
|
|
switch (key) {
|
|
case KeyEvent.VK_W -> visualPanel.offsetY += panStep;
|
|
case KeyEvent.VK_S -> visualPanel.offsetY -= panStep;
|
|
case KeyEvent.VK_A -> visualPanel.offsetX += panStep;
|
|
case KeyEvent.VK_D -> visualPanel.offsetX -= panStep;
|
|
case KeyEvent.VK_PLUS, KeyEvent.VK_EQUALS -> visualPanel.zoom *= 1.1f;
|
|
case KeyEvent.VK_MINUS -> visualPanel.zoom /= 1.1f;
|
|
}
|
|
|
|
repaint();
|
|
}
|
|
|
|
@Override public void keyReleased(KeyEvent e) {}
|
|
@Override public void keyTyped(KeyEvent e) {}
|
|
|
|
@Override
|
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
|
int notches = e.getWheelRotation();
|
|
float factor = (notches > 0) ? 0.9f : 1.1f;
|
|
visualPanel.zoom *= factor;
|
|
repaint();
|
|
}
|
|
|
|
class VisualPanel extends JPanel{
|
|
|
|
private float zoom = 20f; // pixels per unit
|
|
private float offsetX = 0, offsetY = 0; // pan
|
|
private Robot.DataPacketPlus dpp = new Robot.DataPacketPlus(0,0,0,0,0,0,0);
|
|
|
|
public VisualPanel() {
|
|
|
|
addMouseListener(new MouseAdapter() {
|
|
@Override
|
|
public void mouseClicked(MouseEvent e) {
|
|
Point screenPoint = e.getPoint();
|
|
float worldX = (screenPoint.x - getWidth() / 2f - offsetX) / zoom;
|
|
float worldY = -(screenPoint.y - getHeight() / 2f - offsetY) / zoom;
|
|
robot.sendTargetPos(worldX, worldY);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void updateData(Robot.DataPacketPlus dpp) {
|
|
this.dpp = dpp;
|
|
if(dpp.distance()<2500){
|
|
var x = dpp.x() + 0.0393701*dpp.distance()*Math.cos((dpp.yaw()+90)/180*Math.PI);
|
|
var y = dpp.y() + 0.0393701*dpp.distance()*Math.sin((dpp.yaw()+90)/180*Math.PI);
|
|
synchronized (maps){
|
|
maps.add(new Pos(x, y));
|
|
}
|
|
}
|
|
repaint();
|
|
}
|
|
|
|
@Override
|
|
protected void paintComponent(Graphics g) {
|
|
super.paintComponent(g);
|
|
drawScene((Graphics2D) g);
|
|
}
|
|
|
|
private void drawScene(Graphics2D g) {
|
|
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
|
int width = getWidth();
|
|
int height = getHeight();
|
|
|
|
|
|
// Flip back to draw text
|
|
g.scale(1, 1);
|
|
|
|
g.setColor(Color.WHITE);
|
|
g.fillRect(0, 0, width, height);
|
|
|
|
g.translate((double) width / 2 + offsetX, (double) height / 2 + offsetY);
|
|
|
|
g.setColor(Color.BLACK);
|
|
g.drawString(String.format("Position: (%.2f, %.2f)", dpp.x(), dpp.y()), -getWidth() / 2.0f + 10 - offsetX, -getHeight() / 2.0f + 20 - offsetY);
|
|
g.drawString(String.format("Yaw: %.2f°", dpp.yaw()), -getWidth() / 2.0f + 10 - offsetX, -getHeight() / 2.0f + 40 - offsetY);
|
|
g.drawString(String.format("Target Yaw: %.2f°", dpp.t_yaw()), -getWidth() / 2.0f - offsetX + 10, -getHeight() / 2.0f + 60 - offsetY);
|
|
g.drawString(String.format("Zoom: %.1f", zoom), -getWidth() / 2.0f - offsetX + 10, -getHeight() / 2.0f + 80 - offsetY);
|
|
|
|
g.scale(zoom, -zoom); // Y-up
|
|
|
|
int px = Math.round(dpp.x());
|
|
int py = Math.round(dpp.y());
|
|
|
|
int pt_x = Math.round(dpp.t_x());
|
|
int pt_y = Math.round(dpp.t_y());
|
|
|
|
// Target
|
|
g.setColor(Color.GRAY);
|
|
g.fillOval(pt_x - 3, pt_y - 3, 6, 6);
|
|
|
|
// Position dot
|
|
g.setColor(Color.BLUE);
|
|
g.fillOval(px - 5, py - 5, 10, 10);
|
|
|
|
g.setColor(Color.ORANGE);
|
|
|
|
ArrayList<Pos> cln;
|
|
synchronized (maps) {
|
|
cln = new ArrayList<>(maps);
|
|
}
|
|
for (var pos : cln) {
|
|
g.fillOval((int) (pos.x - 1), (int) (pos.y - 2), 2, 2);
|
|
}
|
|
|
|
// Yaw direction
|
|
{
|
|
float yawRad = (float) Math.toRadians(dpp.yaw());
|
|
int dx = (int) (30 * Math.cos(yawRad));
|
|
int dy = (int) (30 * Math.sin(yawRad));
|
|
g.setColor(Color.RED);
|
|
g.drawLine(px, py, px + dx, py + dy);
|
|
}
|
|
|
|
// Target Yaw direction
|
|
{
|
|
float rad = (float) Math.toRadians(dpp.t_yaw());
|
|
int dx = (int) (30 * Math.cos(rad));
|
|
int dy = (int) (30 * Math.sin(rad));
|
|
g.setColor(Color.GREEN);
|
|
g.drawLine(px, py, px + dx, py + dy);
|
|
}
|
|
|
|
// Line to origin
|
|
g.setColor(Color.GREEN.darker());
|
|
g.drawLine(pt_x, pt_y, px, py);
|
|
}
|
|
}
|
|
}
|
|
|