Development
Following the publication of the specifications from Violet, two kinds of development are now possible with the Nabaztag.
HTTP API
The most immediate development to setup relies onthe HTTP API which allows
every Web clients to interact with Violet's servers.
Note that the Web client can be a browser as well as a program.
The existing commands allow:
- retrieving the actual position of the ears
- changing the ears' position
- sending a message from Violet's library or your own MP3
- sending a text message to be reproduced vocally
- sending to a nabcast
- sending a choregraphy, or a visual animation for the rabbit
The HTTP API is widely used on Web sites which allows you to send commands to the rabbit.
It is mainly discussed on forumactif, the Nabaztag forum,
in the API section ; its documentation is available on Violet's site.
NabazLab does not rely on this API, but some of its functionnalities offer some useful tools for using it.
For instance, the choregraphy editor built in Studio
allows you to create and export a choregraphy in a format compatible witht the HTTP API as well as sending it to Violet's server.
Client-server
The aim of NabazLab is to be an alternative to Violet's system through
a development tool and an independant server for the Nabaztag.
This combination allows the creation of special services which would otherwise
not be available or usable from a distant server.
This kind of application is distributed between the server and the rabbit:
-
Rabbit side
The internal firmware of the rabbit cannot be updated but it includes a virtual
machine which is able to execute some programs in the same way of a Java or .NET
virtual machine. All Violet's services are designed like this.
When starting, the virtual machine is empty and the rabbit connects to its server
to get a program to execute. Then, the rabbit connects the server on a regular basis
to retrieve the updates of its program and parameters.
NabazLab contains an assembly language for the virtual machine. Accessible from
a command line, in Studio, from the Service or from any .NET program, it converts
the source of the program to a list of bytecodes understandable by the virtual machine.
The assembly language is a very low level language. Beside the common calculation
and flow's execution control operations, it allows to control some of the Nabaztag's
hardware components. The documentation of this language is available on Violet's web site.
Specific extensions used by NabazLab are described in the Assembly page.
NabazLab Studio
contains a text editor and an embedded server to test your program.
-
Server side
The server controls the rabbit's behaviour by answering its requests based
on external parameters. Some of these parameters cab ne the number of messages
in a mailbox, the sound messages awaiting in a database, the computation of a
byorithm or anhything you can think of.
A complete answer from the server is a set of sounds, midi files, executable
bytecode and parameters for this bytecode.
A partial answer to update only some parameters is also possible.
NabazLab Service
contains a standalone and modular server which can be controlled from a Web interface.
A library allows to create a module and a simple service in just a few lines of C#, VB.NET or Java (J#).
These two components are tightly linked and have to be developed and debugged together.
NabazLab aims at providing a support as well as an environment for these two aspects of the development.
Best of both worlds
It has to be noticed that due to the architecture, it is normally not possible
to get Violet's services and specific services working together.
At one time, the bytecode loaded in the rabbit is either the one from Violet of a particular development.
Despite the fact that it is possible for a module or proxy to modify data
exchanged between the rabbit and Violet's server on the fly to add or modify a service,
this way of doing things is not recommended. Indeed, a minor change from Violet could
break everything
If the two services must work together, the best way to achieve this is to
implement an automated switch between two working modes inside the module:
-
Proxy mode, or Violet
The requests from the rabbit are sent to Violet and answers are
Les requêtes du lapin sont retransmises a Violet et les réponses
retournées au lapin, sans modification. Quand le module souhaite prendre
le contrôle du lapin suite a un évènement extérieur ou chronologique, il
provoque un rechargement de la VM avec son propre bytecode.
-
Server mode or local
When controlling is no more necessary, the first request received by the
rabbit is modified by the module to contain some reinitialization parameters
then sent to Violet. In return, Violet sends an answer containing the original
bytecode and the module reverts to the proxy mode.
Studio
NabazLab Studio is an integrated development environment for the Nabaztag which
works only on Windows.
You can start it by launching NabazLab.Studio.exe.
Choregraphy editor
This editor allows you to work with choregraphy files (.nzdnc).
A choregraphy is a scheduled sequence of rabbit's control operations.
It can already be sent to a rabbit using the HTTP API and it will soon
be possible to use them in the NabazLab server.
Each operation or step can be one the 3 following types:
- Wait
To set a delay between two operations
- Motor
To start one of the ears' motors up to a specified position and in a specified direction
- Light
To change the brightness of one the LEDs by specifying the red, green and blue components
A new choregraphy can be created from the File | New Choregraphy menu item.
The composition screen is divided into three panels:
- On the top left, a rabbit's simulation to preview the choregraphy
- A settings panel under the rabbit, which changes based on the selected operation
- A list of all choregraphy's operations on the right
To create a choregraphy, you select the differents steps to the animation,
and, for each of them, you choose which part of the rabbit to change or the timer
to specify a delay. All the selections are done with the mouse and the keyboard
is used to select the step to modify.
Some functions have a keyboard shortcut:
- Space or Ins to duplicate the selected operation
- Enter to start or stopd the animation preview on the screen
- Del to delete the current operation
- Maj+Up to move the current operation up in the list
- Maj+Down to move the current operation down in the list
Tips and hints:
- The space key is your best friend, if you click on the rabbit without duplicating your last step, the current operation is replaced
- Add an additionnal step at the end of the choregraphy, so that the rabbit executes the preceeding wait operation
- The lights panel below the colors settings is adjustable with the mouse's right button
- The rotation direction of the motors can be inverted by clicking on the middle of the ears' positionning wheel
- The motors' commands are asynchronous, it means that the next step is executed immediately without waiting the ear to reach its final position
- In general, children enjoy the editor and its Send command :-)
The Copy command allows you to copy the choregraphy to your clipboard in a format usable by the HTTP API,
so that you can use it in another application or a Web page.
Program editor
Studio's assembly program editor is still very rough but will be soon updated.
It is interesting because it constantly assemble the program you are editing and can alert with a message in the status bar when a problem occurs.
When the embedded server is active in assembly mode, a backup of the working file allows it to be updated in the rabbit.
Note that the same result can be achieved with a standard external text editor.
Embedded server
The embedded server in Studio is managed from the window which opened at launch.
By default, it is not running but only activated when you check the box Activate after
having eventually modified the TCP port to use and the running mode.
The default port is 8008, which is the same used by NabazLab Service.
As a consequence, without a modification of this port, Studio's embedded server and the Service one
cannot run at the same time.
The two running modes are:
-
Proxy mode
In this mode, the requests from the rabbit are simply sent to Violet's server
and its answers returned to the rabbit.
This allows both to reset the rabbit in its original state without having to reconfigure it,
and also to learn how it works by capturing all the network requests.
-
Assembly mode
The assembly mode, when activated, allows you to select an assembly file (.nzasm)
which will be compiled and sent to the rabbit for being executed.
The server constantly keeps an eye on the source file, in order to compile and transfer it again in case of modification.
In these two modes, it is possible to activate the capture of the network requests
between the rabbit and its server.
You can then record all this network traffic or only a subset of it using the File menu.
Watching the captures
A recorded capture from the embedded server (.nzcap) can be viewed again through the File | Open menu.
As during the capture, some elements exchanged between the rabbit and its server can be recorded separetely or copie to the clipboard.
Service
NabazLab Service is a standalone and modular server for the Nabaztag.
Today, it does only run on Windows but might be ported to other platforms.
Executing NabazLab.Service.exe gives access to the Service menu.
When activated, the Service is configurable through a web interface on the same port used by the rabbit
(which is by default http://localhost:8080).
Installation (optional)
From this menu, it is possible to manage the installation of the Service and its basic running mode.
Once installed as a Windows service, the Service starts when the computer starts and runs in the background.
The Service can also work as a standard executable program thanks to the "Debugging console mode" option found in the menu.
Modules
A module is a .NET library file with a special extension (.nzmod), which can be created using any programming language
(Visual C# Express is recommended and freely available).
When started, the Service automatically loads all modules prensent in its directory.
The installation procedure for a module is then a simple matter of copying the file and restarting the servcice.
For an update, it is necessary to first stop the Service in order to replace the file.
Only the "Proxy" and "Assembly server" modules are included internally in NabazLab,
all others are implemented as modules or plugins.
A sample module is available, which allows you to remotely control the state of the rabbit's lights (NabazLab.RemoteControl.nzmod).
Architecture
A module must refer to the "NabazLab.Core.dll" library.
It contains one or more entry points, some static functions dynamically found using the [ModuleInitializer] attribute.
These functions are called upon startup and register the available modules by calling DeviceHandler.Register(), providing a delegate to one or two functions.
The first function, mandatory, will be in charge of answering to rabbits' requests by relying on the helpers found in "NabazLab.Core.dll".
The second, optional, will define the module's configuration web page.
This mechanism will be soon updated to allow the creation of new modules needing less programming lines, but the principle will stay identical and adaptation will be easy.
Compilation
If you want to create your own module or recompile the sample, it will have to be renamed after each compilation.
Indeed, a bug in the .NET framework prevents to compile a library while giving it a specific extension..
A workaround to this issue is to manually update the default configuration of the MSBuild utility as well as the project file of the module.
Make a backup copy of the "Microsoft.Common.targets" file which should be found in
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727", then open the original file in a text editor.
Search for "TargetExt" and replace the lines below:
<PropertyGroup>
<TargetExt Condition="'$(OutputType)'=='exe'">.exe</TargetExt>
<TargetExt Condition="'$(OutputType)'=='winexe'">.exe</TargetExt>
<TargetExt Condition="'$(OutputType)'=='library'">.dll</TargetExt>
<TargetExt Condition="'$(OutputType)'=='module'">.netmodule</TargetExt>
</PropertyGroup>
By:
<PropertyGroup>
<TargetExt Condition="'$(OutputType)'=='exe' and '$(TargetExt)' == ''">.exe</TargetExt>
<TargetExt Condition="'$(OutputType)'=='winexe' and '$(TargetExt)' == ''">.exe</TargetExt>
<TargetExt Condition="'$(OutputType)'=='library' and '$(TargetExt)' == ''">.dll</TargetExt>
<TargetExt Condition="'$(OutputType)'=='module' and '$(TargetExt)' == ''">.netmodule</TargetExt>
</PropertyGroup>
Then, open your project file (.csproj) in a text editor. In the first tag named "PropertyGroup" (the one which contains the tag named "OutputType") insert:
<TargetExt>.nzmod</TargetExt>
This solution works both for the Framework SDK and Visual Studio.
Compiler
NabazLab Assembly is an inline compiler for the Nabaztag's virtual machine.
Available today only on Windows, it is being adpated for other platforms thanks to Mono.
As Mono works on other platforms than Windows, the Compiler should soon be available for Linux, Mac OS X, Sun Solaris and all BSD flavors..
Usage
The Compiler aims to give other projects a way to integrate and use the possibilities of the NabazLab compiler.
It allows to convert a source code (.nzasm) to three different binary forms:
- Bytecode
The resulting file contains the virtual machine's bytecode. It needs to be inserted with other data before being sent to the rabbit.
- Program
The result is a complete program file, including the sounds if any and the control sum.
- Response
The resulting file contains a complet answer to the rabbit's requests, by adding the identifiers, the frequency and the parameters.
The resulting file has the same name as the source code and the extension depends on the format, respectively ".nzcod", ".nzprg" and ".nzrsp".
The exact syntax of the compiler is:
NabazLab.Assembler.exe <file> [-format:<bytecode|program|response>]
As the inline Compiler, the Service and Studio are also able to compile a source code.
Language
The assembly language of the Nabaztag has been documented by Violet, this document is available on their web site.
NabazLab implements this language, with some additions and assumptions:
- The comments begin with a ';', the rest of the line being ignored (; comment).
- Some labels can be used in the code, preceeded by ':' (:Label).
- All the branching and table instructions can refer to these labels.
- The hexadecimal constants are introduced byt '$' ($F8).
- #constant allows you to specify a constant (#constant Up 4)
- #variable allows you to declare a self iterated offset in the 256 bytes data block (#variable VeryUsefulData)
- The constants and variables are used with '@' (LD R0,@Up)
- #idata allows to declare some data bytes per bytes (#idata $01,$F8,-3).
- #wdata allows to declare some data using words, including labels and then branching tables (#wdata $1234,Label,$1256).
- #base is optional, allowed only at the beginning of the code, and specifies the starting execution address (the default address is the one defined by the rabbit).
Beside the language itself, additional instructions allow to specify to the compiler some parameters to send to the rabbit:
- #transition sets the transition flag in the program frame (#transition 1)
- #frequency sets the frequency for the subsequent requests. 1 for 10 seconds, 2 for 20 seconds, etc...
A frequency sets to 0 generates multilple requests per second (#frequency 0)
- #identifier sets the program identifier (#identifier 1234)
- #parameters adds some bytes to the parameter frame (#parameters 1,2,3,4)
- #sound includes a sound file in the answer and define a self iterated constant (#sound MyMidi sounds\mymidi.mid)
NabazLab assumes that decimal integers are signed, therefore it is not possible to define a value greater than 127 without using the hexadecimal notation.
Decompiler
A decompiler is also included, used for instance during the captures' viewing. It gives good results but does have two issues:
- It cannot always know if a portion of the program is some code or some data,
for instance because of branching tables. In this case, it generates #idata instructions.
- At least one instruction was not documented by Violet ($A9 is an example).
Creating a module
This page describes the creation of a simple module using C# and assembly for the NabazLab Service.
The goal of this module will be to light the rabbit in blue if a file "C:\Blue.txt" exists, otherwise to light it off.
Tools
Even if the .NET Framework SDK would be enough to build this module, we highly recommand the use of Microsoft Visual C# Express.
It does require a registration but is actually downloadable freely from Microsoft, in
french or in
english.
This tutorial has been made with the french version, no other tools are necessary.
Creating the project
We first start by creating a new project, of type library (DLL):
- Use the menu item File | New project,
- Choose Classes libraries,
- In the Name field, enter MyModule,
- Click Ok.
The project is now created and the Class1.cs document is shown.
Configuring dependencies
This configuration will link the project to the NabazLab.Core library:
- Click with the mouse's right button on the References in the Solutions explorer,
- Choose Add a reference,
- Choose the Browse tab,
- Go to NabazLab.Core.dll and select the file,
- Click Ok.
Resources configuration
We will create an emty assembly file and add it to the project:
- Click with the mouse's right button on MyModule in the Solutions explorer,
- Use the Add menu, then New element,
- Select Text file,
- In the Name field, replace with TextFile1.nzasm,
- Click the Add button.
Then, we configure the project so that the file is integrated in the module:
- Use the File | Save all menu item,
- You can optionally modify the Location field, then click on Save,
- Double click on Properties in the Solution explorer,
- Select the Resources tab,
- Click on the link in the middle of the empty document,
- Click the small arrow on the right of Add a ressource, then Add an existing file,
- Navigate to the TextFile1.nzasm, and click on Open.
Creating the assembly code
Switch to the TextFile1.nzasm document, and enter the following text:
#frequency
0
#parameters
$FF
:Loop
LD
R0,0
LD
R1,0
LD
R10,0
SRC
R2,R10
LD
R12,10
LD
R11,0
LED
R11,R12
LD
R11,1
LED
R11,R12
LD
R11,2
LED
R11,R12
LD
R11,3
LED
R11,R12
LD
R11,4
LED
R11,R12
WAIT
10
BRA
Loop
Creating the C# structure
Switch to the Class1.cs document, then modify the header to include all the useful references:
using System;
using System.IO;
using System.Text;
using System.Resources;
using NabazLab.Core.Language;
using NabazLab.Core.Modules;
using NabazLab.Core.Server;
using NabazLab.Core.Protocol;
using NabazLab.Core.Utilities;
All other modifications will be added to the Class1 class definition.
Now, add a random identifier to identify our program as well as its parameters:
static int m_Identifier = (new Random()).Next();
Then add an empty function, which will be called upon each requests from the rabbit (we will define it later):
static ProtocolResponse AnswerTheRabbit(ProtocolRequest Request, IConfiguration Configuration)
{
}
Finally, add the entry point of the module which will be automatically called by the Service thanks to its attribute.
This function registers the previous function as an available module:
[ModuleInitializer]
static void Initializer()
{
DeviceHandler.Register("MyModule", "My first module", AnswerTheRabbit);
}
Encoding answers for the rabbit
The following code must be added to the AnswerTheRabbit() function. First the module says Hello :
Logger.Log(string.Format("\nRequest at {0}", DateTime.Now));
Let's start the real job by creating a table of bytes which will hold the program's parameters of the rabbit.
We only need one byte, to specify the brightness of the blue color.
byte[] Parameters = new byte[1];
Parameters[0] = (byte)(File.Exists("C:\\Blue.txt") ? 255 : 0);
Then we build an answer, with help from the protocol included in NabazLab.
We also specify to the rabbit to repeat its requests as fast as possible:
ProtocolResponse Response = new ProtocolResponse();
Response.Append(new FrequencyFrame(0));
Response.Append(new ParametersFrame(m_Identifier, Parameters));
At this time, the answer is complete only if the rabbit is already running our assembly code.
If this is not the case, we have to provide this code, compiled as bytecode:
if (Request.st == "00" || m_Identifier.ToString("X8") != Request.tc)
{
Logger.Log("Compiling the code");
string Code = Encoding.Default.GetString(Properties.Resources.TextFile1);
Response.Append(new ProgramFrame(m_Identifier, 1, Assembler.Assemble(Code).ByteCode));
}
Here we are, now we can send this answer back to the Service:
Logger.Log(string.Format("Response: {0}", Parameters[0]));
return Response;
Our module is finished, ready to be tested. Now press the F6 key to create the module's file, MyModule.dll.
The complete C# code
using
System; using
System.IO; using
System.Text; using
System.Resources;
using
NabazLab.Core.Language; using
NabazLab.Core.Modules; using
NabazLab.Core.Server; using
NabazLab.Core.Protocol; using
NabazLab.Core.Utilities;
namespace
MyModule
{
public
class
Class1
{
static
int
m_Identifier = (new
Random
()).Next();
static
ProtocolResponse
AnswerTheRabbit(ProtocolRequest
Request, IConfiguration
Configuration)
{
Logger
.Log(string
.Format("\nRequest at {0}"
, DateTime.Now));
byte
[] Parameters = new
byte
[1];
Parameters[0] = (byte
)(File
.Exists("C:\\Blue.txt"
) ? 255 : 0);
ProtocolResponse
Response = new
ProtocolResponse
();
Response.Append(new
FrequencyFrame
(0));
Response.Append(new
ParametersFrame
(m_Identifier, Parameters));
if
(Request.st == "00"
|| m_Identifier.ToString("X8"
) != Request.tc)
{
Logger
.Log("Compiling the code"
);
string
Code = Encoding
.Default.GetString(Properties
.Resources
.TextFile1);
Response.Append(new
ProgramFrame
(m_Identifier, 1, Assembler
.Assemble(Code).ByteCode));
}
Logger
.Log(string
.Format("Response: {0}"
, Parameters[0]));
return
Response;
}
[ModuleInitializer]
static
void
Initializer()
{
DeviceHandler
.Register("MyModule"
, "My first module"
, AnswerTheRabbit);
}
}
}
Testing the module
The module file is ready, it should be located in the
"My Documents\Visual Studio 2005\Projects\MonModule\MyModule\bin\Release" folder.
Note that the version in the Debug folder is generally not up to date and should not be used.
Your Nabaztag must be configured to connect to your PC. To test the module:
- Copy the MyModule.dll file to the folder where NabazLab has been installed,
- Stop the Service or Studio if they are running,
- Drag & drop the MyModule.dll file to NabazLab.Service.exe,
- Open the web interface at http://localhost:8080,
- If necessary, select your module to activate it.
If you use a full version of Visual Studio, the following configuration is easier:
- Double click on Propertues in the Solutions explorer,
- Select the Debug tab,
- Select the option Start an external program,
- Use the Browser button (...) to select the NabazLab.Service.exe file,
- In the Command line parameters field, enter MyModule.dll,
- You can now start directly your module in debugging mode from Visual Studio
For the Express versions, a similar result can be obtained by adding to your solutions, the NabazLab.Core and NabazLab.Service projects.
If you want your module to be automatically loaded by the Service by default, rename it with the .nzmod extension.
To directly compile with this extension, see the procedure described on the Service page.
Conclusion
This basic module is using less than one hundred lines of assembly code and C#.
The NabazLab infrastructure allows you to concentrate your efforts on new, not seen before, functionnalities for the Nabaztag,
and the usage possibilities are only limited by your imagination.
Whatever may be your experiences, we encourage you to share them on the NabazLab forum.
And why not contribute by joining the NabazLab project...
Now have fun with your rabbit!