public class AltosAccel extends AltosUnits {
- public double value(double v) {
- if (AltosConvert.imperial_units)
+ public double value(double v, boolean imperial_units) {
+ if (imperial_units)
return AltosConvert.meters_to_feet(v);
return v;
}
- public String show_units() {
- if (AltosConvert.imperial_units)
+ public double inverse(double v, boolean imperial_units) {
+ if (imperial_units)
+ return AltosConvert.feet_to_meters(v);
+ return v;
+ }
+
+ public String show_units(boolean imperial_units) {
+ if (imperial_units)
return "ft/s²";
return "m/s²";
}
- public String say_units() {
- if (AltosConvert.imperial_units)
+ public String say_units(boolean imperial_units) {
+ if (imperial_units)
return "feet per second squared";
return "meters per second squared";
}
- public int show_fraction(int width) {
+ public int show_fraction(int width, boolean imperial_units) {
return width / 9;
}
}
\ No newline at end of file
return meters_to_feet(meters) / 5280;
}
+ public static double miles_to_meters(double miles) {
+ return feet_to_meters(miles * 5280);
+ }
+
public static double meters_to_mph(double mps) {
return meters_to_miles(mps) * 3600;
}
+ public static double mph_to_meters(double mps) {
+ return miles_to_meters(mps) / 3600;
+ }
+
public static double meters_to_mach(double meters) {
return meters / 343; /* something close to mach at usual rocket sites */
}
return c * 9/5 + 32;
}
+ public static double f_to_c(double c) {
+ return (c - 32) * 5/9;
+ }
+
public static boolean imperial_units = false;
public static AltosDistance distance = new AltosDistance();
public class AltosDistance extends AltosUnits {
- public double value(double v) {
- if (AltosConvert.imperial_units)
+ public double value(double v, boolean imperial_units) {
+ if (imperial_units)
return AltosConvert.meters_to_miles(v);
return v;
}
- public String show_units() {
- if (AltosConvert.imperial_units)
+ public double inverse(double v, boolean imperial_units) {
+ if (imperial_units)
+ return AltosConvert.miles_to_meters(v);
+ return v;
+ }
+
+ public String show_units(boolean imperial_units) {
+ if (imperial_units)
return "miles";
return "m";
}
- public String say_units() {
- if (AltosConvert.imperial_units)
+ public String say_units(boolean imperial_units) {
+ if (imperial_units)
return "miles";
return "meters";
}
- public int show_fraction(int width) {
- if (AltosConvert.imperial_units)
+ public int show_fraction(int width, boolean imperial_units) {
+ if (imperial_units)
return width / 3;
return width / 9;
}
- public int say_fraction() {
- if (AltosConvert.imperial_units)
+ public int say_fraction(boolean imperial_units) {
+ if (imperial_units)
return 1;
return 0;
}
public class AltosHeight extends AltosUnits {
- public double value(double v) {
- if (AltosConvert.imperial_units)
+ public double value(double v, boolean imperial_units) {
+ if (imperial_units)
return AltosConvert.meters_to_feet(v);
return v;
}
- public double parse(String s) throws NumberFormatException {
- double v = Double.parseDouble(s);
- if (AltosConvert.imperial_units)
- v = AltosConvert.feet_to_meters(v);
+ public double inverse(double v, boolean imperial_units) {
+ if (imperial_units)
+ return AltosConvert.feet_to_meters(v);
return v;
}
- public String show_units() {
- if (AltosConvert.imperial_units)
+ public String show_units(boolean imperial_units) {
+ if (imperial_units)
return "ft";
return "m";
}
- public String say_units() {
- if (AltosConvert.imperial_units)
+ public String say_units(boolean imperial_units) {
+ if (imperial_units)
return "feet";
return "meters";
}
- public int show_fraction(int width) {
+ public int show_fraction(int width, boolean imperial_units) {
return width / 9;
}
}
\ No newline at end of file
public static final int pyro_accel_greater = 0x00000002;
public static final String pyro_accel_less_string = "a<";
public static final String pyro_accel_greater_string = "a>";
- public static final String pyro_accel_less_name = "Acceleration less than (m/s²)";
- public static final String pyro_accel_greater_name = "Acceleration greater than (m/s²)";
+ public static final String pyro_accel_less_name = "Acceleration less than";
+ public static final String pyro_accel_greater_name = "Acceleration greater than";
public static final double pyro_accel_scale = 16.0;
public static final int pyro_speed_less = 0x00000004;
public static final int pyro_speed_greater = 0x00000008;
public static final String pyro_speed_less_string = "s<";
public static final String pyro_speed_greater_string = "s>";
- public static final String pyro_speed_less_name = "Speed less than (m/s)";
- public static final String pyro_speed_greater_name = "Speed greater than (m/s)";
+ public static final String pyro_speed_less_name = "Speed less than";
+ public static final String pyro_speed_greater_name = "Speed greater than";
public static final double pyro_speed_scale = 16.0;
public static final int pyro_height_less = 0x00000010;
public static final int pyro_height_greater = 0x00000020;
public static final String pyro_height_less_string = "h<";
public static final String pyro_height_greater_string = "h>";
- public static final String pyro_height_less_name = "Height less than (m)";
- public static final String pyro_height_greater_name = "Height greater than (m)";
+ public static final String pyro_height_less_name = "Height less than";
+ public static final String pyro_height_greater_name = "Height greater than";
public static final double pyro_height_scale = 1.0;
public static final int pyro_orient_less = 0x00000040;
private static HashMap<Integer,String> pyro_to_name = new HashMap<Integer,String>();
+ private static HashMap<Integer,AltosUnits> pyro_to_units = new HashMap<Integer,AltosUnits>();
+
private static HashMap<Integer,Double> pyro_to_scale = new HashMap<Integer,Double>();
- private static void insert_map(int flag, String string, String name, double scale) {
+ private static void insert_map(int flag, String string, String name, AltosUnits units, double scale) {
string_to_pyro.put(string, flag);
pyro_to_string.put(flag, string);
pyro_to_name.put(flag, name);
+ if (units != null)
+ pyro_to_units.put(flag, units);
pyro_to_scale.put(flag, scale);
}
}
public static String pyro_to_name(int flag) {
- if (pyro_to_name.containsKey(flag))
- return pyro_to_name.get(flag);
+ String name;
+ AltosUnits units = null;
+ if (!pyro_to_name.containsKey(flag))
+ return null;
+
+ name = pyro_to_name.get(flag);
+ if (pyro_to_units.containsKey(flag))
+ units = pyro_to_units.get(flag);
+ if (units == null)
+ return name;
+ return String.format ("%s (%s)", name, units.show_units());
+ }
+
+ public static AltosUnits pyro_to_units(int flag) {
+ if (pyro_to_units.containsKey(flag))
+ return pyro_to_units.get(flag);
return null;
}
}
private static void initialize_maps() {
- insert_map(pyro_accel_less, pyro_accel_less_string, pyro_accel_less_name, pyro_accel_scale);
- insert_map(pyro_accel_greater, pyro_accel_greater_string, pyro_accel_greater_name, pyro_accel_scale);
+ insert_map(pyro_accel_less, pyro_accel_less_string, pyro_accel_less_name, AltosConvert.accel, pyro_accel_scale);
+ insert_map(pyro_accel_greater, pyro_accel_greater_string, pyro_accel_greater_name, AltosConvert.accel, pyro_accel_scale);
- insert_map(pyro_speed_less, pyro_speed_less_string, pyro_speed_less_name, pyro_speed_scale);
- insert_map(pyro_speed_greater, pyro_speed_greater_string, pyro_speed_greater_name, pyro_speed_scale);
+ insert_map(pyro_speed_less, pyro_speed_less_string, pyro_speed_less_name, AltosConvert.speed, pyro_speed_scale);
+ insert_map(pyro_speed_greater, pyro_speed_greater_string, pyro_speed_greater_name, AltosConvert.speed, pyro_speed_scale);
- insert_map(pyro_height_less, pyro_height_less_string, pyro_height_less_name, pyro_height_scale);
- insert_map(pyro_height_greater, pyro_height_greater_string, pyro_height_greater_name, pyro_height_scale);
+ insert_map(pyro_height_less, pyro_height_less_string, pyro_height_less_name, AltosConvert.height, pyro_height_scale);
+ insert_map(pyro_height_greater, pyro_height_greater_string, pyro_height_greater_name, AltosConvert.height, pyro_height_scale);
- insert_map(pyro_orient_less, pyro_orient_less_string, pyro_orient_less_name, pyro_orient_scale);
- insert_map(pyro_orient_greater, pyro_orient_greater_string, pyro_orient_greater_name, pyro_orient_scale);
+ insert_map(pyro_orient_less, pyro_orient_less_string, pyro_orient_less_name, null, pyro_orient_scale);
+ insert_map(pyro_orient_greater, pyro_orient_greater_string, pyro_orient_greater_name, null, pyro_orient_scale);
- insert_map(pyro_time_less, pyro_time_less_string, pyro_time_less_name, pyro_time_scale);
- insert_map(pyro_time_greater, pyro_time_greater_string, pyro_time_greater_name, pyro_time_scale);
+ insert_map(pyro_time_less, pyro_time_less_string, pyro_time_less_name, null, pyro_time_scale);
+ insert_map(pyro_time_greater, pyro_time_greater_string, pyro_time_greater_name, null, pyro_time_scale);
- insert_map(pyro_ascending, pyro_ascending_string, pyro_ascending_name, 1.0);
- insert_map(pyro_descending, pyro_descending_string, pyro_descending_name, 1.0);
+ insert_map(pyro_ascending, pyro_ascending_string, pyro_ascending_name, null, 1.0);
+ insert_map(pyro_descending, pyro_descending_string, pyro_descending_name, null, 1.0);
- insert_map(pyro_after_motor, pyro_after_motor_string, pyro_after_motor_name, 1.0);
- insert_map(pyro_delay, pyro_delay_string, pyro_delay_name, pyro_delay_scale);
+ insert_map(pyro_after_motor, pyro_after_motor_string, pyro_after_motor_name, null, 1.0);
+ insert_map(pyro_delay, pyro_delay_string, pyro_delay_name, null, pyro_delay_scale);
- insert_map(pyro_state_less, pyro_state_less_string, pyro_state_less_name, 1.0);
- insert_map(pyro_state_greater_or_equal, pyro_state_greater_or_equal_string, pyro_state_greater_or_equal_name, 1.0);
+ insert_map(pyro_state_less, pyro_state_less_string, pyro_state_less_name, null, 1.0);
+ insert_map(pyro_state_greater_or_equal, pyro_state_greater_or_equal_string, pyro_state_greater_or_equal_name, null, 1.0);
}
{
public class AltosSpeed extends AltosUnits {
- public double value(double v) {
- if (AltosConvert.imperial_units)
+ public double value(double v, boolean imperial_units) {
+ if (imperial_units)
return AltosConvert.meters_to_mph(v);
return v;
}
- public String show_units() {
- if (AltosConvert.imperial_units)
+ public double inverse(double v, boolean imperial_units) {
+ if (imperial_units)
+ return AltosConvert.mph_to_meters(v);
+ return v;
+ }
+
+ public String show_units(boolean imperial_units) {
+ if (imperial_units)
return "mph";
return "m/s";
}
- public String say_units() {
- if (AltosConvert.imperial_units)
+ public String say_units(boolean imperial_units) {
+ if (imperial_units)
return "miles per hour";
return "meters per second";
}
- public int show_fraction(int width) {
+ public int show_fraction(int width, boolean imperial_units) {
return width / 9;
}
}
\ No newline at end of file
public class AltosTemperature extends AltosUnits {
- public double value(double v) {
- if (AltosConvert.imperial_units)
+ public double value(double v, boolean imperial_units) {
+ if (imperial_units)
return AltosConvert.c_to_f(v);
return v;
}
- public String show_units() {
- if (AltosConvert.imperial_units)
+ public double inverse(double v, boolean imperial_units) {
+ if (imperial_units)
+ return AltosConvert.f_to_c(v);
+ return v;
+ }
+
+ public String show_units(boolean imperial_units) {
+ if (imperial_units)
return "°F";
return "°C";
}
- public String say_units() {
- if (AltosConvert.imperial_units)
+ public String say_units(boolean imperial_units) {
+ if (imperial_units)
return "degrees farenheit";
return "degrees celsius";
}
- public int show_fraction(int width) {
+ public int show_fraction(int width, boolean imperial_units) {
return width / 3;
}
}
public abstract class AltosUnits {
- public abstract double value(double v);
+ public abstract double value(double v, boolean imperial_units);
- public abstract String show_units();
+ public abstract double inverse(double v, boolean imperial_units);
- public abstract String say_units();
+ public abstract String show_units(boolean imperial_units);
- public abstract int show_fraction(int width);
+ public abstract String say_units(boolean imperial_units);
- int say_fraction() {
+ public abstract int show_fraction(int width, boolean imperial_units);
+
+ public double parse(String s, boolean imperial_units) throws NumberFormatException {
+ double v = Double.parseDouble(s);
+ return inverse(v, imperial_units);
+ }
+
+ public double parse(String s) throws NumberFormatException {
+ return parse(s, AltosConvert.imperial_units);
+ }
+
+ public double value(double v) {
+ return value(v, AltosConvert.imperial_units);
+ }
+
+ public double inverse(double v) {
+ return inverse(v, AltosConvert.imperial_units);
+ }
+
+ public String show_units() {
+ return show_units(AltosConvert.imperial_units);
+ }
+
+ public String say_units() {
+ return say_units(AltosConvert.imperial_units);
+ }
+
+ public int show_fraction(int width) {
+ return show_fraction(width, AltosConvert.imperial_units);
+ }
+
+ int say_fraction(boolean imperial_units) {
return 0;
}
- private String show_format(int width) {
- return String.format("%%%d.%df %s", width, show_fraction(width), show_units());
+ private String show_format(int width, boolean imperial_units) {
+ return String.format("%%%d.%df %s", width, show_fraction(width, imperial_units), show_units(imperial_units));
+ }
+
+ private String say_format(boolean imperial_units) {
+ return String.format("%%1.%df", say_fraction(imperial_units));
}
- private String say_format() {
- return String.format("%%1.%df", say_fraction());
+ private String say_units_format(boolean imperial_units) {
+ return String.format("%%1.%df %s", say_fraction(imperial_units), say_units(imperial_units));
}
- private String say_units_format() {
- return String.format("%%1.%df %s", say_fraction(), say_units());
+ public String graph_format(int width, boolean imperial_units) {
+ return String.format(String.format("%%%d.%df", width, show_fraction(width, imperial_units)), 0.0);
}
public String graph_format(int width) {
- return String.format(String.format("%%%d.%df", width, show_fraction(width)), 0.0);
+ return graph_format(width, AltosConvert.imperial_units);
+ }
+
+ public String show(int width, double v, boolean imperial_units) {
+ return String.format(show_format(width, imperial_units), value(v, imperial_units));
}
public String show(int width, double v) {
- return String.format(show_format(width), value(v));
+ return show(width, v, AltosConvert.imperial_units);
+ }
+
+ public String say(double v, boolean imperial_units) {
+ return String.format(say_format(imperial_units), value(v, imperial_units));
}
public String say(double v) {
- return String.format(say_format(), value(v));
+ return say(v, AltosConvert.imperial_units);
+ }
+
+ public String say_units(double v, boolean imperial_units) {
+ return String.format(say_units_format(imperial_units), value(v, imperial_units));
}
public String say_units(double v) {
- return String.format(say_units_format(), value(v));
+ return say_units(v, AltosConvert.imperial_units);
}
}
\ No newline at end of file
public class AltosConfigPyroUI
extends AltosUIDialog
- implements ItemListener, DocumentListener
+ implements ItemListener, DocumentListener, AltosUnitsListener
{
AltosConfigUI owner;
Container pane;
}
}
- class PyroItem implements ItemListener, DocumentListener
+ class PyroItem implements ItemListener, DocumentListener, AltosUnitsListener
{
public int flag;
public JRadioButton enable;
public JTextField value;
public JComboBox combo;
AltosConfigPyroUI ui;
+ boolean setting;
public void set_enable(boolean enable) {
if (value != null)
public void itemStateChanged(ItemEvent e) {
set_enable(enable.isSelected());
- ui.set_dirty();
+ if (!setting)
+ ui.set_dirty();
}
public void changedUpdate(DocumentEvent e) {
- ui.set_dirty();
+ if (!setting)
+ ui.set_dirty();
}
public void insertUpdate(DocumentEvent e) {
- ui.set_dirty();
+ if (!setting)
+ ui.set_dirty();
}
public void removeUpdate(DocumentEvent e) {
- ui.set_dirty();
+ if (!setting)
+ ui.set_dirty();
+ }
+
+ public void units_changed(boolean imperial_units) {
+ AltosUnits units = AltosPyro.pyro_to_units(flag);
+
+ if (units != null) {
+ try {
+ double v = units.parse(value.getText(), !imperial_units);
+ set(enabled(), v);
+ } catch (NumberFormatException ne) {
+ set(enabled(), 0.0);
+ }
+ }
}
public void set(boolean new_enable, double new_value) {
+ setting = true;
enable.setSelected(new_enable);
set_enable(new_enable);
if (value != null) {
double scale = AltosPyro.pyro_to_scale(flag);
+ double unit_value = new_value;
+ AltosUnits units = AltosPyro.pyro_to_units(flag);
+ if (units != null)
+ unit_value = units.value(new_value);
String format = "%6.0f";
if (scale >= 10)
format = "%6.1f";
else if (scale >= 100)
format = "%6.2f";
- value.setText(String.format(format, new_value));
+ value.setText(String.format(format, unit_value));
}
if (combo != null)
if (new_value >= AltosLib.ao_flight_boost && new_value <= AltosLib.ao_flight_landed)
combo.setSelectedIndex((int) new_value - AltosLib.ao_flight_boost);
+ setting = false;
}
public boolean enabled() {
}
public double value() {
- if (value != null)
+ if (value != null) {
+ AltosUnits units = AltosPyro.pyro_to_units(flag);
+ if (units != null)
+ return units.parse(value.getText());
return Double.parseDouble(value.getText());
+ }
if (combo != null)
return combo.getSelectedIndex() + AltosLib.ao_flight_boost;
return 0;
}
}
- class PyroColumn {
+ class PyroColumn implements AltosUnitsListener {
public PyroItem[] items;
public JLabel label;
int channel;
for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
if ((AltosPyro.pyro_all & flag) != 0) {
if (items[row].enabled()) {
- System.out.printf ("Flag %x enabled\n", flag);
p.flags |= flag;
p.set_value(flag, items[row].value());
}
row++;
}
}
- System.out.printf ("Pyro %x %s\n", p.flags, p.toString());
return p;
}
+ public void units_changed(boolean imperial_units) {
+ int row = 0;
+ for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1) {
+ if ((AltosPyro.pyro_all & flag) != 0) {
+ items[row].units_changed(imperial_units);
+ row++;
+ }
+ }
+ }
+
public PyroColumn(AltosConfigPyroUI ui, int x, int y, int in_channel) {
channel = in_channel;
}
PyroColumn[] columns;
+ JLabel[] labels;
public void set_pyros(AltosPyro[] pyros) {
for (int i = 0; i < pyros.length; i++) {
owner.set_dirty();
}
+ public void units_changed(boolean imperial_units) {
+ for (int c = 0; c < columns.length; c++)
+ columns[c].units_changed(imperial_units);
+ int r = 0;
+ for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) {
+ String n = AltosPyro.pyro_to_name(flag);
+ if (n != null) {
+ labels[r].setText(n);
+ r++;
+ }
+ }
+ }
+
+ /* A window listener to catch closing events and tell the config code */
+ class ConfigListener extends WindowAdapter {
+ AltosConfigPyroUI ui;
+ AltosConfigUI owner;
+
+ public ConfigListener(AltosConfigPyroUI this_ui, AltosConfigUI this_owner) {
+ ui = this_ui;
+ owner = this_owner;
+ }
+
+ public void windowClosing(WindowEvent e) {
+ ui.setVisible(false);
+ }
+ }
+
public AltosConfigPyroUI(AltosConfigUI in_owner, AltosPyro[] pyros) {
super(in_owner, "Configure Pyro Channels", false);
pane = getContentPane();
pane.setLayout(new GridBagLayout());
+ int nrow = 0;
+ for (int flag = 1; flag < AltosPyro.pyro_all; flag <<= 1)
+ if ((flag & AltosPyro.pyro_all) != 0)
+ nrow++;
+
+ labels = new JLabel[nrow];
+
int row = 1;
for (int flag = 1; flag <= AltosPyro.pyro_all; flag <<= 1) {
c.insets = il;
JLabel label = new JLabel(n);
pane.add(label, c);
+ labels[row-1] = label;
row++;
}
}
columns[i] = new PyroColumn(this, i*2 + 1, 0, i);
columns[i].set(pyros[i]);
}
+ addWindowListener(new ConfigListener(this, owner));
+ AltosPreferences.register_units_listener(this);
+ }
+
+ public void dispose() {
+ AltosPreferences.unregister_units_listener(this);
+ super.dispose();
}
public void make_visible() {
void set_pad_orientation_tool_tip() {
if (pad_orientation_value.isEnabled())
- pad_orientation_value.setToolTipText("How will TeleMetrum be mounted in the airframe");
+ pad_orientation_value.setToolTipText("How will the computer be mounted in the airframe");
else {
if (is_telemetrum())
pad_orientation_value.setToolTipText("Older TeleMetrum firmware must fly antenna forward");
/* Build the UI using a grid bag */
public AltosConfigUI(JFrame in_owner, boolean remote) {
- super (in_owner, "Configure TeleMetrum", false);
+ super (in_owner, "Configure Flight Computer", false);
owner = in_owner;
GridBagConstraints c;
AltosConfigPyroUI pyro_ui;
public void dispose() {
+ if (pyro_ui != null)
+ pyro_ui.dispose();
AltosPreferences.unregister_units_listener(this);
+ super.dispose();
}
/* Listen for events from our buttons */
String cmd = e.getActionCommand();
if (cmd.equals("Pyro")) {
- if (pyro_ui == null && pyros != null) {
+ if (pyro_ui == null && pyros != null)
pyro_ui = new AltosConfigPyroUI(this, pyros);
+ if (pyro_ui != null)
pyro_ui.make_visible();
- }
return;
}
}
public void units_changed(boolean imperial_units) {
+ String v = main_deploy_value.getSelectedItem().toString();
main_deploy_label.setText(get_main_deploy_label());
set_main_deploy_values();
- listener.actionPerformed(new ActionEvent(this, 0, "Reset"));
+ int m = (int) (AltosConvert.height.parse(v, !imperial_units) + 0.5);
+ set_main_deploy(m);
}
public void set_apogee_delay(int new_apogee_delay) {
class AltosVoltage extends AltosUnits {
- public double value(double v) {
+ public double value(double v, boolean imperial_units) {
return v;
}
- public String show_units() {
+ public double inverse(double v, boolean imperial_units) {
+ return v;
+ }
+
+ public String show_units(boolean imperial_units) {
return "V";
}
- public String say_units() {
+ public String say_units(boolean imperial_units) {
return "volts";
}
- public int show_fraction(int width) {
+ public int show_fraction(int width, boolean imperial_units) {
return width / 2;
}
}
class AltosNsat extends AltosUnits {
- public double value(double v) {
+ public double value(double v, boolean imperial_units) {
+ return v;
+ }
+
+ public double inverse(double v, boolean imperial_units) {
return v;
}
- public String show_units() {
+ public String show_units(boolean imperial_units) {
return "Sats";
}
- public String say_units() {
+ public String say_units(boolean imperial_units) {
return "Satellites";
}
- public int show_fraction(int width) {
+ public int show_fraction(int width, boolean imperial_units) {
return 0;
}
}
class AltosPressure extends AltosUnits {
- public double value(double p) {
+ public double value(double p, boolean imperial_units) {
return p;
}
- public String show_units() {
+ public double inverse(double p, boolean imperial_units) {
+ return p;
+ }
+
+ public String show_units(boolean imperial_units) {
return "Pa";
}
- public String say_units() {
+ public String say_units(boolean imperial_units) {
return "pascals";
}
- public int show_fraction(int width) {
+ public int show_fraction(int width, boolean imperial_units) {
return 0;
}
}
class AltosDbm extends AltosUnits {
- public double value(double d) {
+ public double value(double d, boolean imperial_units) {
+ return d;
+ }
+
+ public double inverse(double d, boolean imperial_units) {
return d;
}
- public String show_units() {
+ public String show_units(boolean imperial_units) {
return "dBm";
}
- public String say_units() {
+ public String say_units(boolean imperial_units) {
return "D B M";
}
- public int show_fraction(int width) {
+ public int show_fraction(int width, boolean imperial_units) {
return 0;
}
}