@Override protected void finalizeProcessingInternal( ChunkTypeRequest pattern, IChunk result, Object... parameters) { AbstractVocalModule module = getModule(); IModel model = module.getModel(); IVocalActivationBuffer buffer = getModule().getVocalBuffer(); IChunk error = module.getErrorChunk(); IChunk free = module.getFreeChunk(); IChunk bufferState = error; Object failureMessage = null; IAgent agent = ACTRRuntime.getRuntime().getConnector().getAgent(model); IEfferentCommand vocalizationCommand = agent.getEfferentCommandManager().get(getCommandIdentifier()); IEfferentCommand.ActualState state = IEfferentCommand.ActualState.ABORTED; if (vocalizationCommand != null) { state = vocalizationCommand.getActualState(); failureMessage = vocalizationCommand.getResult(); } String msg = null; if (state == IEfferentCommand.ActualState.COMPLETED) { msg = "Execution of vocalization completed."; bufferState = free; } else { msg = "Execution of vocalization failed [" + state + "] : " + failureMessage; bufferState = error; } if (LOGGER.isDebugEnabled()) LOGGER.debug("Deleting command"); /* * delete the command */ agent.send( new ObjectCommandRequest( ((ISensoryIdentifier) getCommandIdentifier()).getSensor(), agent.getIdentifier(), IObjectCommand.Type.REMOVED, Collections.singleton(getCommandIdentifier()))); if (LOGGER.isDebugEnabled()) LOGGER.debug(msg); if (Logger.hasLoggers(model)) Logger.log(model, Logger.Stream.VOCAL, msg); buffer.setExecutionChunk(bufferState); buffer.setStateChunk(bufferState); buffer.setModalityChunk(bufferState); }
@Override protected double computeHarvestTime( IRequest request, IChunk result, double startTime, Object... parameters) { IIdentifier commandIdentifier = (IIdentifier) parameters[0]; AbstractVocalModule module = getModule(); IModel model = module.getModel(); IAgent agent = ACTRRuntime.getRuntime().getConnector().getAgent(model); VocalizationCommand command = (VocalizationCommand) agent.getEfferentCommandManager().get(commandIdentifier); double computedDuration = getModule().getExecutionTimeEquation().compute(command.getText(), getModule()); double estimatedDuration = command.getEstimatedDuration(); double actualDuration = computedDuration; if (Math.abs(estimatedDuration - computedDuration) >= 0.01) { switch (module.getExecutionTimeResolution()) { case ACTR: actualDuration = computedDuration; break; case CR: actualDuration = estimatedDuration; break; case MINIMUM: actualDuration = Math.min(estimatedDuration, computedDuration); break; case MAXIMUM: actualDuration = Math.max(estimatedDuration, computedDuration); break; } String msg = "CR and jACT-R disagree as to the vocalization duration, " + estimatedDuration + " & " + computedDuration + " respectively. Using " + actualDuration; if (Logger.hasLoggers(model)) Logger.log(model, Logger.Stream.VOCAL, msg); if (LOGGER.isWarnEnabled()) LOGGER.warn(msg); } return startTime + actualDuration; }
/** when a chunk is matched against, we modify its insertion time.. */ @Override protected boolean matchedInternal(IChunk chunk) { if (!_times.containsKey(chunk)) { if (LOGGER.isWarnEnabled()) LOGGER.warn(chunk + " was matched, but is not in the buffer?"); return false; } /* * if LRA, we've done all we need to */ EjectionPolicy policy = getEjectionPolicy(); if (policy == EjectionPolicy.LeastRecentlyAdded || policy == EjectionPolicy.MostRecentlyAdded) return true; /* * now we can tweak the access time, but only if the policy is LRU or LRM */ double oldTime = _times.get(chunk); double newTime = ACTRRuntime.getRuntime().getClock(getModel()).getTime(); _sourceChunks.remove(oldTime); /* * make sure there are no collisions */ while (_sourceChunks.containsKey(newTime) && !chunk.equals(_sourceChunks.get(newTime))) /* * problem of more than one chunk inserted at the same time (could happen * during path-integration) */ newTime += 0.000001; _times.put(chunk, newTime); _sourceChunks.put(newTime, chunk); if (LOGGER.isDebugEnabled()) LOGGER.debug(getName() + " Source Chunks & Times " + _sourceChunks); return true; }
@Override protected IChunk addSourceChunkInternal(IChunk chunkToInsert) { if (LOGGER.isDebugEnabled()) LOGGER.debug("attempting to insert " + chunkToInsert); /* * ok, something will be changing.. */ IChunk errorChunk = getErrorChunk(); /* * did something go wrong? set the states.. */ if (errorChunk.equals(chunkToInsert) || !isValidChunkType(chunkToInsert.getSymbolicChunk().getChunkType())) { if (LOGGER.isDebugEnabled()) LOGGER.debug(getName() + " : " + chunkToInsert + " was error or invalid of chunk type"); setStateChunk(errorChunk); chunkToInsert = null; } /* * all is good, let's set the chunk */ if (chunkToInsert != null) { /* * are we bumping up against the maximum capacity? */ ensureCapacity(); double now = ACTRRuntime.getRuntime().getClock(getModel()).getTime(); double time = Double.MIN_VALUE; /* * if LRA or LRU, time will be now, if modified, we set it as minimum * double value (can't be negative inf because of potential value * collisions, see below) */ switch (getEjectionPolicy()) { case LeastRecentlyAdded: case LeastRecentlyUsed: case MostRecentlyAdded: case MostRecentlyUsed: time = now; break; } /* * problem of more than one chunk inserted at the same time (could happen * if a production fires multiple adds) */ while (_sourceChunks.containsKey(time) && !chunkToInsert.equals(_sourceChunks.get(time))) time += 0.0000001; _sourceChunks.put(time, chunkToInsert); _times.put(chunkToInsert, time); if (LOGGER.isDebugEnabled()) LOGGER.debug(getName() + " Source Chunks & Times " + _sourceChunks); IModel model = getModel(); if (LOGGER.isDebugEnabled() || Logger.hasLoggers(model)) { IMessageBuilder sb = Logger.messageBuilder(); sb.append(getName()) .append(" inserted ") .append(chunkToInsert.getSymbolicChunk().getName()); if (LOGGER.isDebugEnabled()) LOGGER.debug(sb.toString()); Logger.log(model, Logger.Stream.BUFFER, sb); } chunkInserted(chunkToInsert); } return chunkToInsert; }
@Override protected void finishRequest(IRequest request, IActivationBuffer buffer, Object startValue) { final IModel model = buffer.getModel(); VocalizationCommand command = null; IChunk error = model.getDeclarativeModule().getErrorChunk(); IChunk free = model.getDeclarativeModule().getFreeChunk(); IChunk busy = model.getDeclarativeModule().getBusyChunk(); IPerceptualBuffer pBuffer = (IPerceptualBuffer) buffer; String rejection = null; try { command = ((Future<VocalizationCommand>) startValue).get(); } catch (InterruptedException e) { // bail return; } catch (ExecutionException e) { rejection = e.getCause().getMessage(); LOGGER.error("Failed to get vocalization future ", e); } if (command != null && command.getActualState() == ActualState.REJECTED) rejection = "Vocalization was rejected : " + command.getResult(); if (rejection != null) { if (LOGGER.isDebugEnabled()) LOGGER.debug(rejection); if (Logger.hasLoggers(model)) Logger.log(model, Logger.Stream.VOCAL, rejection); pBuffer.setPreparationChunk(error); pBuffer.setStateChunk(error); return; } String msg = "Vocalization prepared."; if (LOGGER.isDebugEnabled()) LOGGER.debug(msg); if (Logger.hasLoggers(model)) Logger.log(model, Logger.Stream.VOCAL, msg); pBuffer.setPreparationChunk(free); /* * now to actually execute, we use another drifting timed event.. two * actually.. */ Future<VocalizationCommand> executeFuture = _vocal.execute(command); double start = ACTRRuntime.getRuntime().getClock(model).getTime(); double procEnd = model.getProceduralModule().getDefaultProductionFiringTime() + start; double execEnd = _vocal.getExecutionTimeEquation().compute(getText(request), _vocal); ProcessTimedEvent procEvent = new ProcessTimedEvent(start, procEnd, executeFuture, buffer); ExecuteTimedEvent execEvent = new ExecuteTimedEvent(start, execEnd, executeFuture, buffer); /* * set some flags */ pBuffer.setProcessorChunk(busy); pBuffer.setExecutionChunk(busy); model.getTimedEventQueue().enqueue(procEvent); model.getTimedEventQueue().enqueue(execEvent); }
@Override protected boolean shouldProcess(IRequest request, Object... parameters) { AbstractVocalModule module = getModule(); IVocalActivationBuffer vBuffer = module.getVocalBuffer(); IModel model = module.getModel(); IChunk busy = module.getBusyChunk(); IIdentifier commandIdentifier = (IIdentifier) parameters[0]; IAgent agent = ACTRRuntime.getRuntime().getConnector().getAgent(model); if (vBuffer.isExecutionBusy()) { String msg = "Vocalizations cannot be executed when the vocal buffer is busy executing. Ignoring request"; if (Logger.hasLoggers(model)) Logger.log(model, Logger.Stream.VOCAL, msg); if (LOGGER.isWarnEnabled()) LOGGER.warn(msg); return false; } if (getModule().getVocalizationSource() == null) { String msg = "No vocalization source could be found. Ignoring request"; if (Logger.hasLoggers(model)) Logger.log(model, Logger.Stream.VOCAL, msg); if (LOGGER.isWarnEnabled()) LOGGER.warn(msg); return false; } if (commandIdentifier == null) { String msg = "No vocalization was prepared. Ignoring request."; if (Logger.hasLoggers(model)) Logger.log(model, Logger.Stream.VOCAL, msg); if (LOGGER.isWarnEnabled()) LOGGER.warn(msg); return false; } if (getCommandIdentifier() != null) { String msg = "Vocalization is already being executed but not passed on. Ignoring old vocalization."; if (Logger.hasLoggers(model)) Logger.log(model, Logger.Stream.VOCAL, msg); if (LOGGER.isWarnEnabled()) LOGGER.warn(msg); setCommandIdentifier(null); } VocalizationCommand command = (VocalizationCommand) agent.getEfferentCommandManager().get(commandIdentifier); if (command == null) { String msg = "No command was found for " + commandIdentifier + ". Something has gone horribly wrong"; /** Error : error */ LOGGER.error(msg); if (Logger.hasLoggers(model)) Logger.log(model, Logger.Stream.VOCAL, msg); return false; } vBuffer.setExecutionChunk(busy); setCommandIdentifier(commandIdentifier); return true; }
protected ProceduralModuleEvent(IProceduralModule source) { super(source); setSimulationTime(ACTRRuntime.getRuntime().getClock(source.getModel()).getTime()); _productions = Collections.EMPTY_LIST; }