/**
* @author Frank Zeyda, Kun Wei
*/
package hijac.cdx;
import javax.realtime.PeriodicParameters;
import javax.realtime.PriorityParameters;
import javax.realtime.PriorityScheduler;
import javax.realtime.RelativeTime;
//import javax.safetycritical.AperiodicEvent;
import javax.safetycritical.AperiodicEventHandler;
import javax.safetycritical.PeriodicEventHandler;
import javax.safetycritical.StorageParameters;
import hijac.cdx.CDxMission;
import hijac.cdx.CDxSafelet;
import hijac.cdx.CallSign;
import hijac.cdx.Constants;
import hijac.cdx.RawFrame;
import hijac.cdx.StateTable;
import hijac.cdx.Vector3d;
import hijac.cdx.javacp.utils.Iterator;
//import hijac.cdx.javacp.utils.Iterator;
import hijac.cdx.javacp.utils.Set;
//import hijac.cdx.javacp.utils.Set;
//import java.util.Iterator;
//import java.util.Set;
/**
* InputFrameHandler is a periodic handler that reads and stores radar frames as
* they arrive. It also updates the shared variable "state" for previous
* aircraft positions.
*/
public class InputFrameHandler extends PeriodicEventHandler {
public final CDxMission mission;
// public final AperiodicEvent reduce;
public final AperiodicEventHandler reduceHandler;
// public InputFrameHandler(CDxMission mission, AperiodicEvent event) {
public InputFrameHandler(CDxMission mission,
AperiodicEventHandler eventHandler) {
super(new PriorityParameters(PriorityScheduler.instance()
.getMaxPriority()), new PeriodicParameters(null,
new RelativeTime(Constants.DETECTOR_PERIOD, 0)),
new StorageParameters(Constants.INPUT_FRAME_HANDLER_BS_SIZE,
null, 0, 0), Constants.INPUT_FRAME_HANDLER_SCOPE_SIZE,
"InputHandler");
this.mission = mission;
// reduce = event;
reduceHandler = eventHandler;
}
@Override
public void handleAsyncEvent() {
CDxSafelet.terminal.writeln("[InputHandler] called");
/* Terminate mission when enough frames have been processes. */
if ((mission.simulator.framesProcessed + mission.simulator.droppedFrames) == Constants.MAX_FRAMES) {
mission.requestSequenceTermination();
mission.dumpResults();
return;
}
/* Performs device access to read the next radar frame. */
mission.simulator.frameBuffer.readFrame();
if (mission.simulator.detectorReady) {
RawFrame frame = mission.simulator.frameBuffer.getFrame();
/* Store the frame and update previous positions. */
StoreFrame(frame);
/* Increment the number of processed frames. */
mission.simulator.framesProcessed++;
/* Release ReducerHandler to perform the voxel hashing. */
// reduce.fire();
reduceHandler.release();
} else {
/* If the detector is not ready, read the next frame and drop it. */
RawFrame drop = mission.simulator.frameBuffer.getFrame();
System.out.println("A frame has been dropped.");
/* Increment the number of dropped frames. */
mission.simulator.droppedFrames++;
}
}
/* This method correspond to the StoreFrame action in the S anchor. */
public void StoreFrame(RawFrame frame) {
/* Update shared data that holds previous aircraft positions. */
updateState();
/* Read the frame into the shared variable. */
mission.getFrame().copy(frame);
System.out.println("A new frame has been read.");
}
/**
* This method records the current positions of all aircrafts in the shared
* state variable of type StateTable.
*/
public void updateState() {
RawFrame frame = mission.getFrame();
/* Used to determine disappeared aircrafts in the state table. */
Set vanished = mission.getState().getCallSigns();
for (int i = 0, pos = 0; i < frame.planeCnt; i++) {
/* Get the current position of the next aircraft. */
final float x = frame.positions[3 * i];
final float y = frame.positions[3 * i + 1];
final float z = frame.positions[3 * i + 2];
/* Get the call sign of the next aircraft. */
final byte[] cs = new byte[Constants.LENGTH_OF_CALLSIGN];
for (int j = 0; j < cs.length; j++) {
cs[j] = frame.callsigns[pos + j];
}
/* Advance index for call sign. */
pos += cs.length;
/* Create a new call sign. */
CallSign callsign = new CallSign(cs);
/* The aircrafts is in view; remove from the vanished set. */
vanished.remove(callsign);
/* Get old position from the state */
final Vector3d old_pos = mission.getState().get(new CallSign(cs));
if (old_pos == null) {
/* We have detected a new aircraft. */
/*
* Note that the callsign object is not actually inserted into
* the StateTable but duplicated by the logic of the put method
* below.
*/
mission.getState().put(callsign, x, y, z);
} else {
/*
* If the aircraft is already recorded in the stable table
* simply update its position.
*/
old_pos.set(x, y, z);
}
}
StateTable state = mission.getState();
/*
* Finally remove all aircrafts from the state table that have
* disappeared from the radar in the current frame. This is important in
* order to give them a zero velocity when they re-enter, a requirement
* of our model.
*/
for (Iterator iter = vanished.iterator(); iter.hasNext();) {
state.remove((CallSign) iter.next());
}
}
}