package edu.colostate.vchill.chill;
import edu.colostate.vchill.ChillDefines;
import edu.colostate.vchill.socket.SocketUtil;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
/**
* Scan segment header.
* Defines a single scan segment or volume
* A scan segment describes a portion (or a complete) volume
*
* @author Jochen Deyke
* @version 2006-08-09
*/
public class ChillScanSeg extends ChillHeader {
public static final int MAX_SEGNAME_LENGTH = 16;
/**
* size (in bytes) of this header (including ChillHeaderHeader, but not including extraData)
*/
public static final int BYTE_SIZE = ChillHeaderHeader.BYTE_SIZE +
5 * ChillDefines.FLOAT_BYTE_SIZE +
MAX_SEGNAME_LENGTH +
3 * ChillDefines.FLOAT_BYTE_SIZE +
2 * ChillDefines.INT_BYTE_SIZE + //enums
5 * ChillDefines.INT_BYTE_SIZE + //unsigned
5 * ChillDefines.FLOAT_BYTE_SIZE +
4 * ChillDefines.INT_BYTE_SIZE + //unsigned
MAX_SEGNAME_LENGTH +
ChillDefines.FLOAT_BYTE_SIZE;
/**
* Modes in which the antenna can scan
*/
enum ScanType {
PPI, /**
* PPI (Plan Position Indicator) Mode
*/
RHI, /**
* RHI (Range Height Indicator) Mode
*/
FIXED, /**
* Fixed pointing angle mode
*/
MANPPI, /**
* Manual PPI mode (elevation does not step automatically)
*/
MANRHI, /**
* Manual RHI mode (azimuth does not step automatically)
*/
IDLE, /**
* IDLE mode, radar is not scanning
*/
LAST
}
/**
* Indicates the object the antenna is currently tracking
*/
enum FollowMode {
NONE, /**
* Radar is not tracking any object
*/
SUN, /**
* Radar is tracking the sun
*/
VEHICLE, /**
* Radar is tracking a vehicle
*/
LAST
}
/**
* Scan Optimizer parameters
*/
static class ScanOptimizer {
public float rmax_km;
public float htmax_km;
public float res_m;
}
/**
* Manual azimuth position. Used in pointing and Manual PPI/RHI modes
*/
public float az_manual;
/**
* Manual elevation position. Used in pointing and Manual PPI/RHI modes
*/
public float el_manual;
/**
* Azimuth start. If>360 implies don't care
*/
public float az_start;
/**
* Elevation start. If>360 implies don't care
*/
public float el_start;
/**
* Antenna scan rate, in degrees/sec
*/
public float scan_rate;
public String segname; //[MAX_SEGNAME_LENGTH]; /**< Name of this scan segment */
/**
* Scan optimizer parameters
*/
ScanOptimizer opt = new ScanOptimizer();
/**
* Indicates the object being followed (tracked) by the antenna
*/
FollowMode follow_mode;
/**
* Antenna scanning mode
*/
ScanType scan_type;
/**
* Scan segment flags. See SF_... above
*/
public /*unsigned*/ int scan_flags;
/**
* Volume number, increments linearly
*/
public /*unsigned*/ int volume_num;
/**
* Sweep number within the current volume
*/
public /*unsigned*/ int sweep_num;
/**
* Timeout for this scan, in seconds, if nonzero
*/
public /*unsigned*/ int time_limit;
/**
* if nonzero, archive image of specified sweep
*/
public /*unsigned*/ int webtilt;
/**
* Left limit used in sector scan
*/
public float left_limit;
/**
* Right limit used in sector scan
*/
public float right_limit;
/**
* Upper limit used in sector scan
*/
public float up_limit;
/**
* Lower limit used in sector scan
*/
public float down_limit;
/**
* Antenna step, used to increment az (in RHI) or el (in PPI) if max_sweeps is zero
*/
public float step;
/**
* Indicates that a set of discrete angles is specified for az or el
*/
public /*unsigned*/ int max_sweeps;
/**
* Sweep at which the clutter filter switch from filter 1 to 2
*/
public /*unsigned*/ int filter_break_sweep;
/**
* Clutter filter for sweeps 1 to filter_break_sweep
*/
public /*unsigned*/ int clutter_filter1;
/**
* Clutter filter for sweeps >= filter_break_sweep
*/
public /*unsigned*/ int clutter_filter2;
public String project; //[MAX_SEGNAME_LENGTH]; /**< Project name - used to organize scans + data */
/**
* Current fixed angle (az in RHI, el in PPI)
*/
public float current_fixed_angle;
public ChillScanSeg() {
super(new ChillHeaderHeader(ChillDefines.GEN_MOM_DATA, BYTE_SIZE));
super.extraData = new byte[0];
}
/**
* Constructs a header by reading initial values from a DataInput.
*
* @param in the DataInput to read initialization values from
*/
public ChillScanSeg(final DataInput in, final ChillHeaderHeader header) throws IOException {
super(header);
assert header.recordType == ChillDefines.HSK_ID_SCAN_SEG;
assert header.headerLength - ChillScanSeg.BYTE_SIZE >= 0;
this.az_manual = in.readFloat();
this.el_manual = in.readFloat();
this.az_start = in.readFloat();
this.el_start = in.readFloat();
this.scan_rate = in.readFloat();
this.segname = SocketUtil.readString(in, MAX_SEGNAME_LENGTH);
this.opt.rmax_km = in.readFloat();
this.opt.htmax_km = in.readFloat();
this.opt.res_m = in.readFloat();
this.follow_mode = FollowMode.values()[in.readInt()];
this.scan_type = ScanType.values()[in.readInt()];
this.scan_flags = in.readInt();
this.volume_num = in.readInt();
this.sweep_num = in.readInt();
this.time_limit = in.readInt();
this.webtilt = in.readInt();
this.left_limit = in.readFloat();
this.right_limit = in.readFloat();
this.up_limit = in.readFloat();
this.down_limit = in.readFloat();
this.step = in.readFloat();
this.max_sweeps = in.readInt();
this.filter_break_sweep = in.readInt();
this.clutter_filter1 = in.readInt();
this.clutter_filter2 = in.readInt();
this.project = SocketUtil.readString(in, MAX_SEGNAME_LENGTH);
this.current_fixed_angle = in.readFloat();
in.readFully(super.extraData = new byte[header.headerLength - ChillScanSeg.BYTE_SIZE]);
}
/**
* Writes this header to a DataOut
*
* @param out the DataOutput to write values to
*/
public void write(final DataOutput out) throws IOException {
assert header.recordType == ChillDefines.HSK_ID_SCAN_SEG;
assert header.headerLength == ChillScanSeg.BYTE_SIZE + extraData.length;
super.header.write(out);
out.writeFloat(this.az_manual);
out.writeFloat(this.el_manual);
out.writeFloat(this.az_start);
out.writeFloat(this.el_start);
out.writeFloat(this.scan_rate);
SocketUtil.writeString(this.segname, out, MAX_SEGNAME_LENGTH);
out.writeFloat(this.opt.rmax_km);
out.writeFloat(this.opt.htmax_km);
out.writeFloat(this.opt.res_m);
out.writeInt(this.follow_mode.ordinal());
out.writeInt(this.scan_type.ordinal());
out.writeInt(this.scan_flags);
out.writeInt(this.volume_num);
out.writeInt(this.sweep_num);
out.writeInt(this.time_limit);
out.writeInt(this.webtilt);
out.writeFloat(this.left_limit);
out.writeFloat(this.right_limit);
out.writeFloat(this.up_limit);
out.writeFloat(this.down_limit);
out.writeFloat(this.step);
out.writeInt(this.max_sweeps);
out.writeInt(this.filter_break_sweep);
out.writeInt(this.clutter_filter1);
out.writeInt(this.clutter_filter2);
SocketUtil.writeString(this.project, out, MAX_SEGNAME_LENGTH);
out.writeFloat(this.current_fixed_angle);
out.write(this.extraData);
}
}