package org.jactr.modules.pm.motor.six; /* * default logging */ import java.util.Map; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jactr.core.chunktype.IChunkType; import org.jactr.core.slot.IConditionalSlot; import org.jactr.core.slot.ISlot; import org.jactr.modules.pm.motor.IMotorModule; import org.jactr.modules.pm.motor.command.IMotorTimeEquation; import org.jactr.modules.pm.motor.command.IMovement; /** * @author harrison */ public class DefaultPreparationTimeEquation implements IMotorTimeEquation { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(DefaultPreparationTimeEquation.class); static public final String TIME_PER_FEATURE = "TimePerFeature"; private double _timePerFeature = 0.05; private boolean _firstRun = true; public double compute(IMovement movement, IMotorModule module) { if (_firstRun) { try { _timePerFeature = Double.parseDouble(module .getParameter(TIME_PER_FEATURE)); } catch (Exception e) { _timePerFeature = 0.05; } _firstRun = false; } Map<String, Object> features = generateSlotMap(movement); double prepTime = features.size() * _timePerFeature; IMovement last = module.getLastMovement(movement.getMuscleIdentifier()); if (last != null) { if (LOGGER.isDebugEnabled()) LOGGER.debug("Comparing current movement " + movement + " to last movement " + last); /* * calculate the savings */ Map<String, Object> oldFeatures = generateSlotMap(last); if (movement.getChunkTypeRequest().getChunkType() == last.getChunkTypeRequest() .getChunkType()) { prepTime -= _timePerFeature; if (features.get(IMotorModule.MUSCLE_SLOT).equals( oldFeatures.get(IMotorModule.MUSCLE_SLOT))) { prepTime -= _timePerFeature; features.remove(IMotorModule.MUSCLE_SLOT); oldFeatures.remove(IMotorModule.MUSCLE_SLOT); /* * now we iterate through the remaining features. any non-null matches * are a further reudction */ for (Map.Entry<String, Object> entry : features.entrySet()) if (entry.getValue() != null) if (entry.getValue().equals(oldFeatures.get(entry.getKey()))) prepTime -= _timePerFeature; } } } return Math.max(_timePerFeature, prepTime); } protected Map<String, Object> generateSlotMap(IMovement movement) { Map<String, Object> rtn = new TreeMap<String, Object>(); IChunkType movementType = movement.getChunkTypeRequest().getChunkType(); for (ISlot slot : movementType.getSymbolicChunkType().getSlots()) rtn.put(slot.getName(), slot.getValue()); for (ISlot slot : movement.getChunkTypeRequest().getSlots()) if (((IConditionalSlot)slot).getCondition()==IConditionalSlot.EQUALS) { if (rtn.containsKey(slot.getName())) rtn.put(slot.getName(), slot.getValue()); else if (LOGGER.isWarnEnabled()) LOGGER.warn("Ignoring invalid slot " + slot + " for chunk type " + movementType); } if (LOGGER.isDebugEnabled()) LOGGER.debug("Feature set for "+movement+" : "+rtn); return rtn; } }