rusefi/java_console/ui/src/main/java/com/rusefi/TriggerImage.java

356 lines
12 KiB
Java
Raw Normal View History

2015-07-10 06:01:56 -07:00
package com.rusefi;
import com.rusefi.config.generated.Fields;
2015-08-29 13:01:22 -07:00
import com.rusefi.trigger.WaveState;
2015-07-10 06:01:56 -07:00
import com.rusefi.ui.engine.UpDownImage;
import com.rusefi.ui.util.FrameHelper;
import com.rusefi.ui.util.UiUtils;
import com.rusefi.waves.EngineReport;
2015-08-29 12:02:36 -07:00
import org.jetbrains.annotations.NotNull;
2015-07-10 06:01:56 -07:00
import javax.swing.*;
import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
2015-07-10 06:01:56 -07:00
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
2015-08-29 13:01:22 -07:00
import java.util.Date;
2015-07-10 06:01:56 -07:00
import java.util.List;
/**
* This utility produces images of trigger signals supported by rusEFI
* <p>
2016-04-09 10:02:13 -07:00
* 06/23/15
2020-06-09 17:08:16 -07:00
* Andrey Belomutskiy, (c) 2013-2020
2015-07-10 06:01:56 -07:00
*/
public class TriggerImage {
2016-04-09 10:02:13 -07:00
private static final String TRIGGERTYPE = "TRIGGERTYPE";
private static final String OUTPUT_FOLDER = "triggers";
private static final String INPUT_FILE_NAME = "triggers.txt";
2018-10-12 12:03:21 -07:00
private static final String TOP_MESSAGE = StartupFrame.LINK_TEXT;
2016-04-09 10:02:13 -07:00
private static final String DEFAULT_WORK_FOLDER = ".." + File.separator + "unit_tests";
private static final int WHEEL_BORDER = 20;
private static final int WHEEL_DIAMETER = 300;
private static final int SMALL_DIAMETER = 250;
2015-07-10 06:01:56 -07:00
/**
* number of extra frames
*/
2015-08-29 13:01:22 -07:00
public static int EXTRA_COUNT = 1;
2015-07-10 06:01:56 -07:00
private static String getTriggerName(TriggerWheelInfo triggerName) {
switch (triggerName.id) {
case Fields.TT_TT_MAZDA_MIATA_NA:
return "Miata NA";
case Fields.TT_TT_MAZDA_MIATA_NB1:
return "Miata NB";
case Fields.TT_TT_SUBARU_SVX:
return "Subaru SVX";
case Fields.TT_TT_HONDA_1_24:
return "Honda 1+24";
case Fields.TT_TT_SUBARU_7_6:
return "Subaru 7/6";
case Fields.TT_TT_GM_LS_24:
return "GM 24x";
case Fields.TT_TT_GM_7X:
return "GM 7x";
case Fields.TT_TT_ONE:
return "Single Tooth";
case Fields.TT_TT_2JZ_1_12:
return "2JZ 1/12";
case Fields.TT_TT_JEEP_18_2_2_2:
return "18/2/2/2";
case Fields.TT_TT_RENIX_44_2_2:
return "44/2/2";
case Fields.TT_TT_RENIX_66_2_2_2:
return "66/2/2/2";
case Fields.TT_TT_TOOTHED_WHEEL_36_1:
return "36/1";
case Fields.TT_TT_TOOTHED_WHEEL_36_2:
return "36/2";
case Fields.TT_TT_TOOTHED_WHEEL_60_2:
return "60/2";
}
return triggerName.triggerName;
}
public static void main(String[] args) throws InvocationTargetException, InterruptedException {
2016-04-09 10:02:13 -07:00
final String workingFolder;
2015-07-10 06:01:56 -07:00
if (args.length != 1) {
2016-04-09 10:02:13 -07:00
workingFolder = DEFAULT_WORK_FOLDER;
2015-08-29 12:02:36 -07:00
} else {
2016-04-09 10:02:13 -07:00
workingFolder = args[0];
2015-07-10 06:01:56 -07:00
}
FrameHelper f = new FrameHelper();
JPanel content = new JPanel(new BorderLayout());
2015-08-29 13:01:22 -07:00
final TriggerPanel triggerPanel = new TriggerPanel() {
2015-07-10 06:01:56 -07:00
@Override
public Dimension getPreferredSize() {
return new Dimension((1 + EXTRA_COUNT) * WIDTH, 480);
}
};
JPanel topPanel = new JPanel(new FlowLayout());
content.add(topPanel, BorderLayout.NORTH);
content.add(triggerPanel, BorderLayout.CENTER);
f.showFrame(content);
f.getFrame().setSize(900, 700);
2015-07-10 06:01:56 -07:00
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
try {
generateImages(workingFolder, triggerPanel, topPanel, content);
2015-07-10 06:01:56 -07:00
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
});
System.exit(-1);
2015-07-10 06:01:56 -07:00
}
private static void generateImages(String workingFolder, TriggerPanel trigger, JPanel topPanel, JPanel content) throws IOException {
2018-02-28 20:31:58 -08:00
String fileName = workingFolder + File.separator + INPUT_FILE_NAME;
BufferedReader br = new BufferedReader(new FileReader(fileName));
2015-07-10 06:01:56 -07:00
2018-02-28 20:31:58 -08:00
System.out.println("Reading " + fileName);
2015-07-10 06:01:56 -07:00
String line;
while ((line = br.readLine()) != null) {
2015-08-29 12:02:36 -07:00
if (line.trim().startsWith("#")) {
// skipping a comment
continue;
}
2015-07-10 06:01:56 -07:00
if (line.startsWith(TRIGGERTYPE)) {
readTrigger(br, line, trigger, topPanel, content);
2015-07-10 06:01:56 -07:00
}
}
}
private static void readTrigger(BufferedReader reader, String line, TriggerPanel triggerPanel, JPanel topPanel, JPanel content) throws IOException {
TriggerWheelInfo triggerWheelInfo = TriggerWheelInfo.readTriggerWheelInfo(line, reader);
// if (triggerWheelInfo.id != Fields.TT_TT_SUBARU_7_6)
2015-07-10 06:01:56 -07:00
// return;
topPanel.removeAll();
JPanel firstWheelControl = createWheelPanel(triggerWheelInfo.getFirstWheeTriggerSignals());
topPanel.add(firstWheelControl);
topPanel.add(StartupFrame.createLogoLabel());
if (!triggerWheelInfo.waves.get(1).list.isEmpty()) {
JPanel secondWheelControl = createWheelPanel(triggerWheelInfo.getSecondWheeTriggerSignals());
topPanel.add(secondWheelControl);
}
UiUtils.trueLayout(topPanel);
UiUtils.trueLayout(content);
triggerPanel.tdcPosition = triggerWheelInfo.tdcPosition;
List<WaveState> waves = triggerWheelInfo.waves;
2015-08-29 12:02:36 -07:00
EngineReport re0 = new EngineReport(waves.get(0).list, 720, 720 * (1 + EXTRA_COUNT));
2015-12-15 19:01:31 -08:00
System.out.println(re0);
2015-08-29 12:02:36 -07:00
EngineReport re1 = new EngineReport(waves.get(1).list, 720, 720 * (1 + EXTRA_COUNT));
2017-02-13 21:02:59 -08:00
EngineReport re2 = new EngineReport(waves.get(2).list, 720, 720 * (1 + EXTRA_COUNT));
2015-08-29 12:02:36 -07:00
triggerPanel.removeAll();
UpDownImage upDownImage0 = new UpDownImage(re0, "trigger");
2016-06-04 14:01:42 -07:00
upDownImage0.showMouseOverText = false;
2015-08-29 12:02:36 -07:00
triggerPanel.add(upDownImage0);
UpDownImage upDownImage1 = new UpDownImage(re1, "trigger");
2016-06-04 14:01:42 -07:00
upDownImage1.showMouseOverText = false;
2015-08-29 13:01:22 -07:00
2017-02-13 21:02:59 -08:00
UpDownImage upDownImage2 = new UpDownImage(re2, "trigger");
upDownImage2.showMouseOverText = false;
2015-08-29 13:01:22 -07:00
2017-02-13 21:02:59 -08:00
boolean isSingleSensor = re1.getList().isEmpty();
boolean isThirdVisible = !re2.getList().isEmpty();
int height;
if (isSingleSensor) {
height = 1;
} else if (isThirdVisible) {
height = 3;
} else {
height = 2;
}
triggerPanel.setLayout(new GridLayout(height, 1));
if (!isSingleSensor)
2015-08-29 12:02:36 -07:00
triggerPanel.add(upDownImage1);
2017-02-13 21:02:59 -08:00
if (isThirdVisible)
triggerPanel.add(upDownImage2);
2015-08-29 12:02:36 -07:00
triggerPanel.name = getTriggerName(triggerWheelInfo);
// triggerPanel.id = "#" + triggerWheelInfo.id;
2015-08-29 12:02:36 -07:00
UiUtils.trueLayout(triggerPanel);
UiUtils.trueRepaint(triggerPanel);
content.paintImmediately(content.getVisibleRect());
2016-04-09 10:02:13 -07:00
new File(OUTPUT_FOLDER).mkdir();
UiUtils.saveImage(OUTPUT_FOLDER + File.separator + "trigger_" + triggerWheelInfo.id + ".png", content);
}
@NotNull
private static JPanel createWheelPanel(List<TriggerSignal> wheel) {
JPanel clock = new JPanel() {
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.black);
for (int i = 0; i < wheel.size(); i++) {
TriggerSignal current = wheel.get(i);
drawRadialLine(g, current.angle);
double nextAngle = i == wheel.size() - 1 ? 360 + wheel.get(0).angle : wheel.get(i + 1).angle;
int arcDuration = (int) (nextAngle - current.angle);
if (current.state == 1) {
g.drawArc(WHEEL_BORDER, WHEEL_BORDER, WHEEL_DIAMETER, WHEEL_DIAMETER, (int) current.angle, arcDuration);
} else {
int corner = WHEEL_BORDER + (WHEEL_DIAMETER - SMALL_DIAMETER) / 2;
g.drawArc(corner, corner, SMALL_DIAMETER, SMALL_DIAMETER, (int) current.angle, arcDuration);
}
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(WHEEL_DIAMETER + 2 * WHEEL_BORDER, WHEEL_DIAMETER + 2 * WHEEL_BORDER);
}
};
// clock.setBackground(Color.orange);
return clock;
}
private static void drawRadialLine(Graphics g, double angle) {
int center = WHEEL_BORDER + WHEEL_DIAMETER / 2;
// converting to 'drawArc' angle convention
angle = 90 + angle;
double radianAngle = Math.toRadians(angle);
int smallX = (int) (SMALL_DIAMETER / 2 * Math.sin(radianAngle));
int smallY = (int) (SMALL_DIAMETER / 2 * Math.cos(radianAngle));
int largeX = (int) (WHEEL_DIAMETER / 2 * Math.sin(radianAngle));
int largeY = (int) (WHEEL_DIAMETER / 2 * Math.cos(radianAngle));
g.drawLine(center + smallX, center + smallY, center + largeX, center + largeY);
2015-08-29 12:02:36 -07:00
}
2015-07-10 06:01:56 -07:00
2015-08-29 12:02:36 -07:00
@NotNull
static List<WaveState> convertSignalsToWaves(List<TriggerSignal> signals) {
/**
* todo: what does this code do? does this work?
* looks to be repeating trigger share couple of times? but not visible on images somehow?
*/
List<TriggerSignal> toShow = new ArrayList<>(signals);
2015-07-10 06:01:56 -07:00
for (int i = 1; i <= 2 + EXTRA_COUNT; i++) {
for (TriggerSignal s : signals)
toShow.add(new TriggerSignal(s.waveIndex, s.state, s.angle + i * 720));
2015-07-10 06:01:56 -07:00
}
List<WaveState> waves = new ArrayList<>();
waves.add(new WaveState());
waves.add(new WaveState());
2017-02-13 21:02:59 -08:00
waves.add(new WaveState());
2015-07-10 06:01:56 -07:00
for (TriggerSignal s : toShow) {
WaveState.trigger_value_e signal = (s.state == 0) ? WaveState.trigger_value_e.TV_LOW : WaveState.trigger_value_e.TV_HIGH;
2015-07-10 06:01:56 -07:00
WaveState waveState = waves.get(s.waveIndex);
2015-07-10 06:01:56 -07:00
waveState.handle(signal, s.angle);
}
for (WaveState wave : waves)
wave.wrap();
2015-08-29 12:02:36 -07:00
return waves;
2015-07-10 06:01:56 -07:00
}
@NotNull
static List<TriggerSignal> readSignals(BufferedReader reader, int count) throws IOException {
String line;
String[] tokens;
List<TriggerSignal> signals = new ArrayList<>();
2015-07-10 06:01:56 -07:00
int index = 0;
while (index < count) {
line = reader.readLine();
if (line.trim().startsWith("#"))
continue;
tokens = line.split(" ");
if (tokens.length < 4)
throw new IllegalStateException("Unexpected [" + line + "]");
int signalIndex = Integer.parseInt(tokens[2]);
int signalState = Integer.parseInt(tokens[3]);
double angle = Double.parseDouble(tokens[4]);
2015-07-10 06:01:56 -07:00
TriggerSignal s = new TriggerSignal(signalIndex, signalState, angle);
// System.out.println(s);
signals.add(s);
index++;
2015-07-10 06:01:56 -07:00
}
return signals;
}
2015-07-10 06:01:56 -07:00
public static int angleToTime(double prevUp) {
return (int) (prevUp);
2015-07-10 06:01:56 -07:00
}
private static class TriggerPanel extends JPanel {
public String name = "";
public String id;
2017-02-21 08:46:49 -08:00
public double tdcPosition;
2015-07-10 06:01:56 -07:00
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.black);
2015-08-29 13:01:22 -07:00
int w = getWidth();
2016-04-09 10:02:13 -07:00
int off = g.getFontMetrics().stringWidth(TOP_MESSAGE);
g.drawString(TOP_MESSAGE, w - off, g.getFont().getSize());
2015-08-29 13:01:22 -07:00
2016-04-09 10:02:13 -07:00
String line = new Date().toString();
2015-08-29 13:01:22 -07:00
off = g.getFontMetrics().stringWidth(line);
g.drawString(line, w - off, 2 * g.getFont().getSize());
2015-07-10 06:01:56 -07:00
Font f = g.getFont();
g.setFont(new Font(f.getName(), Font.BOLD, f.getSize() * 3));
int h = getHeight();
g.drawString(name, 0, (int) (h * 0.75));
if (id != null)
g.drawString(id, 0, (int) (h * 0.9));
2017-02-21 08:46:49 -08:00
g.setColor(Color.green);
int tdcFontSize = (int) (f.getSize() * 1.5);
g.setFont(new Font(f.getName(), Font.BOLD, tdcFontSize));
g.drawString("tdcPosition " + formatTdcPosition(), 0, tdcFontSize);
int tdcX = (int) (w / 720.0 * tdcPosition);
g.drawLine(tdcX, 0, tdcX, h);
}
private String formatTdcPosition() {
if ((int) tdcPosition == tdcPosition)
return Integer.toString((int) tdcPosition);
return Double.toString(tdcPosition);
2015-07-10 06:01:56 -07:00
}
}
}