/// <summary> /// Fires the action pattern. /// /// This method fires the current action / sense / sense-act or /// competence of the pattern. In case of firing an action / sense /// / sense-act, the method points to the next element in the /// pattern and returns FireResult(True, None) if the current /// action / sense / sense-act was successful (i.e. evaluated to /// True) and not the last action in the sequence, in which case /// it returns FireResult(False, None) and resets the action /// pattern. /// /// If the current element is a competence, then competence is /// returned as the next element by returning /// FireResult(True, competence), and the action pattern is /// reset. /// </summary> /// <returns>The result of firing the action pattern.</returns> public override FireResult fire() { log.Debug("Fired"); FireArgs args = new FireArgs(); CopiableElement element = elements[elementIdx]; if (element is POSHAction || element is POSHSense) { bool result; if (element is POSHAction) { result = ((POSHAction)element).fire().continueExecution(); } else { result = ((POSHSense)element).fire().continueExecution(); } if (!result) { log.Debug(string.Format("Action/Sense {0} failed", element.getName())); elementIdx = 0; args.FireResult = result; args.Time = DateTime.Now; BroadCastFireEvent(args); return(new FireResult(false, null)); } // check if we've just fired the last action elementIdx += 1; if (elementIdx >= elements.Count) { elementIdx = 0; args.FireResult = result; args.Time = DateTime.Now; BroadCastFireEvent(args); return(new FireResult(false, null)); } args.FireResult = result; args.Time = DateTime.Now; BroadCastFireEvent(args); return(new FireResult(true, null)); } else if (element is Competence) { // we have a competence elementIdx = 0; args.FireResult = true; args.Time = DateTime.Now; BroadCastFireEvent(args); return(new FireResult(true, element)); } return(null); }
/// <summary> /// Initialises the action pattern. /// /// The log domain is set to [AgentId].AP.[patternName] /// </summary> /// <param name="agent">The corresponding agent.</param> /// <param name="patternName">The name of the action pattern.</param> /// <param name="elements">The sequence of actions or senses and /// an optional competence as the final element.</param> /// </param> public ActionPattern(Agent agent, string patternName, CopiableElement []elements) : base(string.Format("AP.{0}", patternName),agent) { name = patternName; this.elements = (elements.Length > 0) ? new List<CopiableElement>(elements) : new List<CopiableElement>(); this.elementIdx = 0; log.Debug("Created"); }
/// <summary> /// Initialises the competence element. /// /// The log domain is set to [AgentName].CE.[element_name]. /// </summary> /// <param name="agent">The competence element's agent.</param> /// <param name="elementName">The name of the competence element.</param> /// <param name="trigger">The element's trigger</param> /// <param name="element">The element to fire (Action,Competence or ActionPattern).</param> /// <param name="maxRetries">The maximum number of retires. If this is set /// to a negative number, it is ignored.</param> public CompetenceElement(Agent agent, string elementName, Trigger trigger, CopiableElement element, int maxRetries) : base(string.Format("CE.{0}", elementName), agent) { this.name = elementName; this.trigger = trigger; this.element = element; this.maxRetries = maxRetries; this.retries = 0; log.Debug("Created"); }
/// <summary> /// Initialises the result of firing an element. /// /// For a more detailed description of the arguments, read the /// class documentation. /// </summary> /// <param name="continueExecution">If we want to continue executing the current /// part of the plan.</param> /// <param name="nextElement">The next plan element to fire.</param> public FireResult(bool continueExecution, CopiableElement nextElement) { continueExecuting = continueExecution; if (continueExecution && nextElement is CopiableElement) // copy the next element, if there is one // FIX: @swen: I do not see the need for copying loads of elements when they can be referenced instead. // FIXME: @ check if this still works when not cloned next = (ElementCollection)nextElement.copy(); else next = null; // FIX: @swen: here must be an error in the original implementation I just uncommented the next line because it seemed wrong // next = nextElement; }
/// <summary> /// Fires the drive element. /// /// This method fires the current drive element and always /// returns None. It uses the slip-stack architecture to determine /// the element to fire in the next step. /// </summary> /// <returns>The result returned is null.</returns> public override FireResult fire() { FireResult result; FireArgs args = new FireArgs(); log.Debug("Fired"); // if our element is an action, we just fire it and do // nothing afterwards. That's because we can only have an action // as an element, if it is the drive element's root element. // Hence, we didn't descend in the plan tree and can keep // the same element. if (element is POSHAction || element.GetType().IsSubclassOf(typeof(POSHAction))) { ((POSHAction)element).fire(); element = root; args.FireResult = false; args.Time = DateTime.Now; BroadCastFireEvent(args); return(null); } // the element is a competence or an action pattern result = ((ElementCollection)element).fire(); args.FireResult = false; args.Time = DateTime.Now; BroadCastFireEvent(args); if (result.continueExecution()) { // if we have a new next element, store it as the next // element to execute CopiableElement next = result.nextElement(); if (next is CopiableElement) { element = next; } } else { // we were told not to continue the execution -> back to root // We must not call reset() here, as that would also reset // the firing frequency of the element. element = root; } return(null); }
/// <summary> /// Initialises the result of firing an element. /// /// For a more detailed description of the arguments, read the /// class documentation. /// </summary> /// <param name="continueExecution">If we want to continue executing the current /// part of the plan.</param> /// <param name="nextElement">The next plan element to fire.</param> public FireResult(bool continueExecution, CopiableElement nextElement) { continueExecuting = continueExecution; if (continueExecution && nextElement is CopiableElement) { // copy the next element, if there is one // FIX: @swen: I do not see the need for copying loads of elements when they can be referenced instead. // FIXME: @ check if this still works when not cloned next = (ElementCollection)nextElement.copy(); } else { next = null; } // FIX: @swen: here must be an error in the original implementation I just uncommented the next line because it seemed wrong // next = nextElement; }
// TODO: replace root which should be a polymoph type (maybe create superclass) /// <summary> /// Initialises the drive element. /// /// The log domain is set to [AgentName].DE.[element_name] /// </summary> /// <param name="agent">The element's agent.</param> /// <param name="elementName">The name of the drive element.</param> /// <param name="trigger">The trigger of the element.</param> /// <param name="root">The element's root element. /// root is either POSH.strict.Action, POSH.strict.Competence or POSH.strict.ActionPattern /// </param> /// <param name="maxFreq">The maximum frequency at which is element is /// fired. The frequency is given in milliseconds between /// invocation. A negative number disables this feature.</param> public DriveElement(Agent agent, string elementName, Trigger trigger, CopiableElement root, long maxFreq) : base(string.Format("DE.{0}", elementName), agent) { this.name = elementName; this.trigger = trigger; this.root = root; this.element = root; this.maxFreq = maxFreq; // the timestamp when it was last fired this.lastFired = -100000L; log.Debug("Created"); this.agent = agent; this.isLatched = false; this.behaviours = new List<Behaviour>(); foreach (POSHSense sense in trigger.senses) this.behaviours.Add(sense.behaviour); }
// TODO: replace root which should be a polymoph type (maybe create superclass) /// <summary> /// Initialises the drive element. /// /// The log domain is set to [AgentName].DE.[element_name] /// </summary> /// <param name="agent">The element's agent.</param> /// <param name="elementName">The name of the drive element.</param> /// <param name="trigger">The trigger of the element.</param> /// <param name="root">The element's root element. /// root is either POSH.strict.Action, POSH.strict.Competence or POSH.strict.ActionPattern /// </param> /// <param name="maxFreq">The maximum frequency at which is element is /// fired. The frequency is given in milliseconds between /// invocation. A negative number disables this feature.</param> public DriveElement(Agent agent, string elementName, Trigger trigger, CopiableElement root, long maxFreq) : base(string.Format("DE.{0}", elementName), agent) { this.name = elementName; this.trigger = trigger; this.root = root; this.element = root; this.maxFreq = maxFreq; // the timestamp when it was last fired this.lastFired = -100000L; log.Debug("Created"); this.agent = agent; this.isLatched = false; this.behaviours = new List <Behaviour>(); foreach (POSHSense sense in trigger.senses) { this.behaviours.Add(sense.behaviour); } }
/// <summary> /// Fires the drive element. /// /// This method fires the current drive element and always /// returns None. It uses the slip-stack architecture to determine /// the element to fire in the next step. /// </summary> /// <returns>The result returned is null.</returns> public override FireResult fire() { FireResult result; FireArgs args = new FireArgs(); log.Debug("Fired"); // if our element is an action, we just fire it and do // nothing afterwards. That's because we can only have an action // as an element, if it is the drive element's root element. // Hence, we didn't descend in the plan tree and can keep // the same element. if (element is POSHAction || element.GetType().IsSubclassOf(typeof(POSHAction))) { ((POSHAction)element).fire(); element = root; args.FireResult = false; args.Time = DateTime.Now; BroadCastFireEvent(args); return null; } // the element is a competence or an action pattern result = ((ElementCollection)element).fire(); args.FireResult = false; args.Time = DateTime.Now; BroadCastFireEvent(args); if (result.continueExecution()) { // if we have a new next element, store it as the next // element to execute CopiableElement next = result.nextElement(); if (next is CopiableElement) element = next; } else // we were told not to continue the execution -> back to root // We must not call reset() here, as that would also reset // the firing frequency of the element. element = root; return null; }
/// <summary> /// Resets the drive element to its root element, /// and resets the firing frequency. /// </summary> public override void reset() { log.Debug("Reset"); element = root; lastFired = -100000L; }
/// <summary> /// Sets the elements of an action pattern. /// /// Calling this method also resets the action pattern. /// </summary> /// <param name="elements">The list of elements of the action patterns. /// A sequence of Actions. An additional Competence can be the /// last Element of the ActionPattern.</param> public void SetElements(CopiableElement [] elements) { this.elements = new List<CopiableElement>(elements); reset(); }
/// <summary> /// Resets the drive element to its root element, /// and resets the firing frequency. /// </summary> public override void reset() { log.Debug("Reset"); element = root; lastFired = -100000L; }