Flow of development

 

The following illustrates the flow of development using the OPEN-R SDK.

 

(1)   Design your objects

 

You must design the functions of the objects you are going to create, as well as

the flow of data between these objects. For example, in the case of designing an

object for tracking a pink ball, the object must receive image data, it must detect

a pink ball in the image, and it must send command data for moving the head

toward the ball.

 

(2)   Design the data type for inter-object communication

 

You must choose an appropriate data type to carry messages between objects.

For example, you can choose OFbkImageVectorData for input data and

OCommandVectorData for output data.

 

(3)   Description of stub.cfg

 

The connection between the entry points (where the message is received) and the

actual member functions of the core class is described with specified form in a

file called stub.cfg (stub configuration file).

In stub.cfg, we also describe the services that send and receive data to/from other

objects. By executing a tool named ¡¥stubgen2¡¦, the intermediate files are created

from stub.cfg, which are needed for compiling purposes.

 

(4)   Implementation of a core class

 

You must implement the core class of your object, which includes the functions

specified by stub.cfg, the four DoXXX() member functions (which are always

implemented on the core class) and other member functions.

 

(5) Decide the configuration of your .ocf file

The configuration of objects at run-time is specified here.

 

(6) Build

 

You build an executable file for your object by linking with other necessary libraries.

 

(7) Edit the setting files

 

You must edit the setting files needed at run-time. The following are the relevant setting files. OBJECT.CFG Description of objects to be executed CONNECT.CFG Description of connections between objects DESIGNDB.CFG Description of files with paths, which are accessed by objects at run-time

 

(8) Execution on AIBO

 

The following files are copied to the specified directory on an AIBO

Programming Memory Stick.

¡E OPEN-R directory

¡E Execution file (.BIN)

¡E Edited setting files

¡E Data files such as motion and sound

After creating a wireless LAN environment for connecting AIBO with your PC,

insert an AIBO Programming Memory Stick into AIBO and boot it.

 

(9) Debugging

 

If you happen to have bugs in your program, you can debug them by using

special debugging macros, such as OSYSPRINT and OSYSLOG1, as well as

other error information, from the messages that are printed in the wireless LAN

console.

Basic OPEN-R Program Constructs

OPEN-R Objects

An OPENR object is more like a UNIX process. Each executable file in the final

program (with a .bin extension) corresponds to one object. Each object communicates

with other objects by passing messages. Each message consists of a selector (which is

an integer) and some data The flow of execution is event-driven.

 

1. Object waits for messages to arrive.

 

2. Once a message arrives, it calls the corresponding method based on the selector. The method ¡V selector combinations are specified in the stub.cfg file. The arguments for the method are the data included in the message.

The method might pass messages to other objects.

 

3. Wait for more messages.

 

Inter-object communication

The object that sends a message is called the ¡§subject¡¨, while the object that receives

the message is called the ¡§observer¡¨.

To send a message, the subject first sends a ¡¥NotifyEvent¡¦ to an observer or set of

observers. The subject then waits for a ¡¥ReadyEvent¡¦ from the observer. The

¡¥ReadyEvent¡¦ from the observer back to the subject can either be:

 

a) ASSERT_READY ¡V if the observer is ready to receive a message

from the subject.

b) DEASSERT-READY ¡V if the observer is not ready to receive a

message

 

Objects are single-threaded. They cannot process more than one message at a time. If

the observer receives a new message when it is processing some other message, then

the new message is put in the message-queue. Each object has one message-queue.

 

Core classes ¡V entry points, member functions, doXXX() functions,

Each object has a corresponding core class. A core classes is a C++ class that defines

the object¡¦s data and methods.

Here is an example of a simple Class[1].

#include <OPENR/OObject.h>

#include <OPENR/OSubject.h>

#include <OPENR/OObserver.h>

#include "def.h"

class SampleClass : public OObject {

public:

SampleClass();

virtual ~SampleClass() {}

OSubject* subject[numOfSubject];

OObserver* observer[numOfObserver];

virtual OStatus DoInit(const OSystemEvent& event);

virtual OStatus DoStart(const OSystemEvent& event);

virtual OStatus DoStop(const OSystemEvent& event);

virtual OStatus DoDestroy(const OSystemEvent& event);

//Describe the member functions corresponding to Notify,

//Control, Ready, Connect method.

};

The different parts of the sample program are explained below:

 

#include <OPENR/OObject.h>

#include <OPENR/OSubject.h>

#include <OPENR/OObserver.h>

#include "def.h"

OSubject.h has the necessary method declarations for the Subjects while

OObserver.h has the corresponding declarations for the Observers. The def.h

file is generated by the stubgen program (which will be discussed later).

class SampleClass : public OObject {

All core classes in OPENR are and must be inherited from OObject. This is very

similar to Object class in Java.

OSubject* subject[numOfSubject];

OObserver* observer[numOfObserver];

This indicates the number of subjects and the observers that the class will have.

Every program must have these. The def.h file defines the numOfSubject and

numOfObserver.

virtual OStatus DoInit(const OSystemEvent& event);

The DoInit() method is called at startup to initialize all the instances and variables.

virtual OStatus DoStart(const OSystemEvent& event);

The DoStart() Method executes right after DoInit() finishes execution.

virtual OStatus DoStop(const OSystemEvent& event);

virtual OStatus DoDestroy(const OSystemEvent& event);

The DoStop() Method is called at shutdown. This is followed by DoDestroy() Method

which destroys all the subject and observer instances, and calls the destructor

function.

In addition to these four methods, at least four other methods have to be defined to

enable inter object communication:

Control Method

This method is used by the subject to receive the connection results with its

observers.

Connect Method

This method is used by the observer to receive the connection results.

Notify Method

This method is used by the observer to receive a message from the subject.

Ready Method

This method is used by the subject to receive the ASSERT-READY and the

DEASSERT-READY notifications.

The DoXXX( ) Method MACROs

In most cases, you will have to include all these macros in every core

class you make.

DoInit( )

NEW_ALL_SUBJECT_AND_OBSERVER

This registers the necessary number of subjects and observers.

REGISTER_ALL_ENTRY

This registers the connection to services offered by other objects.

SET_ALL_READY_AND_NOTIFY_ENTRY

This registers all entry points.

DoStart( )

ENABLE_ALL_SUBJECT

This enables all the subjects

ASSERT_READY_TO_ALL_OBSERVER

This sends ASSERT_READY to all subjects.

DoStop( )

DISABLE_ALL_SUBJECT

This disables all subjects of core class.

DEASSERT_READY_TO_ALL_OBSERVER

This sends a DEASSERT_READY to all connecting subjects.

DoDestroy( )

DELETE_ALL_SUBJECT_AND_OBSERVER

This deletes all observer and subjects.

Message Passing

When the observer is ready to receive data from the subject, the observer sends the

subject an ASSERT-READY message.

___________________________________________________________________________________

void SampleObserver::SendAssertReady()

{

observer[obsfunc1]->AssertReady( );

}

___________________________________________________________________________________

When the subject receives the ASSERT-READY signal, it sends the observer the

data.

___________________________________________________________________________________

void SampleSubject::Ready(const OReadyEvent& event)

{

char str[32];

strcpy(str, ¡§Some Text Message¡¨);

subject[sbjFunc2]->SetData(str,sizeof(str));

subject[sbjFunc2]->NotifyObservers( );

}

___________________________________________________________________________________

When the observer receives the data, it sends an ASSERT_READY again.

___________________________________________________________________________________

void SampleObserver::Notify(const ONotifyEvent& event)

{

const char* text = (const char*)event.Data(0);

observer[sbjFunc1]->AssertReady();

}