Skip to content

Diagram pepper abstraction

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ΒΆ

classDiagram
    class Pepper {
        -pepperActionEventQueue : ConcurrentLinkedQueue<AbstractPepperActionEvent>
        -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ΒΆ


graph LR
    subgraph "Pepper Class - Action Queue System"
        speak[say&#40String phrase&#41\nPublic\nCreate PepperSpeechEvent] --Call method--> addQueue 
        animate[animate&#40String animationName&#41\nPublic\nCreate PepperAnimationEvent] --Call method--> addQueue
        addQueue[addToEventQueue&#40AbstractPepperActionEvent event&#41\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&#40&#41\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&#40QiContext context&#41\nPublic\nSets global QiContext variable\nto provided context. If the context \nis not null,process the event queue] --Sets global QiContext variable--> handleQueue
    end