001package jmri.jmrix.rps.swing.debugger; 002 003import java.awt.FlowLayout; 004 005import javax.swing.BoxLayout; 006import javax.swing.JLabel; 007import javax.swing.JPanel; 008import javax.swing.JTextField; 009import javax.vecmath.Point3d; 010 011import jmri.jmrix.rps.Distributor; 012import jmri.jmrix.rps.Engine; 013import jmri.jmrix.rps.Measurement; 014import jmri.jmrix.rps.MeasurementListener; 015import jmri.jmrix.rps.Reading; 016import jmri.jmrix.rps.ReadingListener; 017 018/** 019 * Pane for manual operation and debugging of the RPS system. 020 * <p> 021 * All index numbers here are 1-based, so they are the same as the RPS hardware 022 * number. 023 * 024 * @author Bob Jacobsen Copyright (C) 2008 025 */ 026public class DebuggerTimePane extends JPanel 027 implements ReadingListener, MeasurementListener { 028 029 public DebuggerTimePane() { 030 super(); 031 032 NUMSENSORS = Engine.instance().getMaxReceiverNumber(); 033 034 times = new JTextField[NUMSENSORS + 1]; 035 residuals = new JLabel[NUMSENSORS + 1]; 036 times[0] = null; 037 residuals[0] = null; 038 for (int i = 1; i <= NUMSENSORS; i++) { 039 times[i] = new JTextField(10); 040 times[i].setText(""); 041 residuals[i] = new JLabel(" "); 042 } 043 } 044 045 public void dispose() { 046 // separate from data source 047 Distributor.instance().removeReadingListener(this); 048 Distributor.instance().removeMeasurementListener(this); 049 } 050 051 private java.text.NumberFormat nf; 052 053 int NUMSENSORS; 054 055 protected JTextField[] times; 056 private final JLabel[] residuals; 057 058 public void initComponents() { 059 060 nf = java.text.NumberFormat.getInstance(); // I18N format 061 nf.setMinimumFractionDigits(1); 062 nf.setMaximumFractionDigits(1); 063 nf.setGroupingUsed(false); 064 065 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 066 067 JPanel p1; 068 JPanel p3 = new JPanel(); 069 p3.setLayout(new java.awt.GridLayout(NUMSENSORS, 2)); 070 071 for (int i = 1; i <= NUMSENSORS; i++) { 072 p1 = new JPanel(); 073 p1.setLayout(new FlowLayout()); 074 p1.add(new JLabel("r" + i + ":")); 075 p1.add(times[i]); 076 p3.add(p1); 077 p1 = new JPanel(); 078 p1.add(new JLabel("r-t: ")); 079 p1.add(residuals[i]); 080 p3.add(p1); 081 } 082 add(p3); 083 } 084 085 void setResidual(int i, Measurement m) { 086 if (times[i].getText().isEmpty()) { 087 residuals[i].setText(""); // just blank out 088 return; 089 } 090 try { 091 if (Engine.instance().getReceiver(i) == null) { 092 residuals[i].setText(""); // just blank out 093 return; 094 } 095 Point3d p = Engine.instance().getReceiverPosition(i); 096 Point3d x = new Point3d((float) m.getX(), (float) m.getY(), (float) m.getZ()); 097 098 double rt = p.distance(x) / Engine.instance().getVSound(); 099 int res = (int) (rt - m.getReading().getValue(i)) - Engine.instance().getOffset(); 100 residuals[i].setText("" + res); 101 log.debug(" residual {} from {} vs {}", res, p, x); 102 } catch (Exception e) { 103 residuals[i].setText(""); // just blank out 104 } 105 } 106 107 @Override 108 public void notify(Reading r) { 109 // Display this set of time values 110 for (int i = 1; i <= Math.min(r.getNValues(), times.length - 1); i++) { 111 times[i].setText(nf.format(r.getValue(i))); // I18N format 112 } 113 } 114 115 @Override 116 public void notify(Measurement m) { 117 try { 118 for (int i = 1; i <= NUMSENSORS; i++) { 119 setResidual(i, m); 120 } 121 } catch (Exception e) { 122 log.error("Error setting residual: ", e); 123 } 124 } 125 126 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DebuggerTimePane.class); 127 128}