package org.jactr.modules.pm.motor.buffer.event; /* * default logging */ import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.commonreality.efferent.IEfferentCommand; import org.commonreality.identifier.IIdentifier; import org.jactr.core.queue.timedevents.AbstractTimedEvent; import org.jactr.core.runtime.ACTRRuntime; import org.jactr.modules.pm.motor.IMotorModule; import org.jactr.modules.pm.motor.command.IMovement; public class MotorTimedEvent extends AbstractTimedEvent { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(MotorTimedEvent.class); private IMovement _movement; private IMotorModule _motor; private double _driftOffset = 0.05; private Set<IEfferentCommand.ActualState> _driftSet; private MotorTimedEvent _driftedTimedEvent; public MotorTimedEvent(IMovement movement, IMotorModule module, double driftOffset, Collection<IEfferentCommand.ActualState> driftStates, double startTime, double endTime) { _movement = movement; _motor = module; _driftOffset = driftOffset; _driftSet = new HashSet<IEfferentCommand.ActualState>(driftStates); setTimes(startTime, endTime); } public Set<IEfferentCommand.ActualState> getDriftStates() { return Collections.unmodifiableSet(_driftSet); } public double getDriftOffset() { return _driftOffset; } public IMovement getMovement() { return _movement; } synchronized public MotorTimedEvent getDriftedTimedEvent() { MotorTimedEvent mte = this; while (mte._driftedTimedEvent != null) mte = mte._driftedTimedEvent; return mte; } @Override public void fire(double currentTime) { synchronized (this) { super.fire(currentTime); } if (LOGGER.isDebugEnabled()) LOGGER.debug("Firing motor event for movement : " + getMovement().getChunkTypeRequest() + " @ " + currentTime); IEfferentCommand command = getMotorCommand(); /* * command may be null, if CR has not responded yet. */ if (command == null) { if (LOGGER.isDebugEnabled()) LOGGER.debug("IEfferentCommand not available, drifting"); drift(); } else { IEfferentCommand.ActualState state = command.getActualState(); if (_driftSet.contains(state)) { if (LOGGER.isDebugEnabled()) LOGGER.debug("State is " + state + " drifting"); drift(); } else { if (LOGGER.isDebugEnabled()) LOGGER.debug("State is " + state + " officially firing " + command.getResult()); fireInternal(currentTime); } } } protected void fireInternal(double currentTime) { } private void drift() { if (LOGGER.isDebugEnabled()) LOGGER.debug("Drifting event to " + (getEndTime() + _driftOffset)); MotorTimedEvent newEvent = instantiateDrift(_movement, _motor, _driftOffset, _driftSet); _driftedTimedEvent = newEvent; _motor.getBuffer().enqueueTimedEvent(newEvent); } protected MotorTimedEvent instantiateDrift(IMovement movement, IMotorModule module, double driftOffset, Collection<IEfferentCommand.ActualState> driftSet) { return new MotorTimedEvent(movement, module, driftOffset, driftSet, getStartTime(), getEndTime() + driftOffset); } protected IEfferentCommand getMotorCommand() { IIdentifier commandId = _movement.getCommandIdentifier(); IEfferentCommand command = ACTRRuntime.getRuntime().getConnector() .getAgent(_motor.getModel()).getEfferentCommandManager().get(commandId); return command; } }