## Pepper Abstraction Design --- ### Introduction The Pepper robot is a complex system that can be controlled by a variety of different actions. To make the system more manageable, we've decided implement abstraction and encapsulation in the classes related to Pepper controls. This way, we can easily add new action events in the future. All these classes inherit from the `AbstractPepperActionEvent` class. ### Problems 1. The Pepper robot functions with a system that only allows one action to be executed at a time, per action category. This means that, for example, when two speech actions are executed at the same time, the application will crash due to a `RuntimeException` being thrown. Due to this fact, whenever the execution of multiple processes overlap, the application will crash. 2. Besides the first problem, for the Pepper robot to be able to execute any actions, it is required to have a QiContext available. This context is only provided in a class that extends the `RobotLifecycleCallbacks` class. This means, that whenever the class does not extend this class, the robot will be unable to execute any actions. ### Solution To prevent the application from crashing, we've decided to implement a queue system in the `Pepper` class. This system allows us to queue any new actions that need to be executed whenever another action is already being executed. This way, we can prevent the application throwing a `RuntimeException` and thus crashing. To tackle the second problem, we've decided to implement a system where the Pepper class has a global variable, which holds the current QiContext. This means, that whenever a user decides to execute an action, and no current QiContext is available, the action will be queued until a QiContext is available. This means that we can queue several actions at once without any exceptions being thrown. ### Diagrams #### Class Diagram ```mermaid classDiagram class Pepper { -pepperActionEventQueue : ConcurrentLinkedQueue -isAnimating : AtomicBoolean -isSpeaking : AtomicBoolean +latestContext : QiContext +addToEventQueue(AbstractPepperActionEvent event) +provideQiContext(QiContext context) -processEventQueue() } class AbstractPepperActionEvent { +getAction() EPepperAction } class PepperSpeechEvent { +phrase : String +locale : Locale +PepperSpeechEvent(String phrase, Locale locale) +getSay(QiContext context) Say } class PepperAnimationEvent { +PepperAnimationEvent(String animationName) +PepperAnimationEvent(String animationName, IAnimationCompletedListener listener) +getAnimation(QiContext context) Animate +animationName : String +IAnimationCompletedListener : IAnimationCompletedListener } Pepper <|-- AbstractPepperActionEvent PepperSpeechEvent <|-- AbstractPepperActionEvent PepperAnimationEvent <|-- AbstractPepperActionEvent ``` #### Queue System in Pepper class ```mermaid graph LR subgraph "Pepper Class - Action Queue System" speak[say(String phrase)\nPublic\nCreate PepperSpeechEvent] --Call method--> addQueue animate[animate(String animationName)\nPublic\nCreate PepperAnimationEvent] --Call method--> addQueue addQueue[addToEventQueue(AbstractPepperActionEvent event)\nPublic\nAdd provided event to event queue] --Add to queue--> queue[Event Queue\nPrivate\nQueue containing all events that\nneed to be executed] addQueue --Call method--> handleQueue[processEventQueue()\nPrivate\nCheck whether there is a context\navailable, and whether an event\nis currently being executed.\nExecutes the next event in the Queue] queue <.-> handleQueue provideCtx[provideQiContext(QiContext context)\nPublic\nSets global QiContext variable\nto provided context. If the context \nis not null,process the event queue] --Sets global QiContext variable--> handleQueue end ```