Doc URBI

Pour le urbiengine-irobot

documentation des périphériques

(book compiled from )

Guillaume Deslandes

Gégoire Le Blan

Traduction de l'anglais Antoine (zelig) Hue

This document is released under the Attribution-NonCommercial-NoDerivs 2.0 Creative Commons licence (http://creativecommons.org/licenses/by-nc-nd/2.0/deed.en).


Table of Contents

1. Introduction
2. Démarrage rapide
3. Premières commandes
Préface
Liste rapide des périphériques
Des commandes simples
4. irobot-create.devices
Préface
Motors
Sensors
Bumpers
Wall Detector
Virtual Wall Detector
Cliff Detectors
Battery
Buttons
Speaker
Command
Odometry
5. Exemples de fonctions avec URBI
Préface
Fonctions de déplacement
Basée sur l'odométrie
Basée sur le temps
Fonctions de démonstration
Les démos intégrées
demos simples
6. Dépannage et FAQ
Dépannage
Questions fréquemments demandées
A. Copyright

List of Tables

3.1. caractéristiques des périphériques

Chapter 1. Introduction

Cette documentation contiens des informations à propos du URBI engine du iRobot Create (iRobot URBI engine, ou iRobot engine pour faire court).

Vous serez intéressé de lire des informations à propos du iRobot Create à irobot.com/create Si vous n'êtes pas encore familiarisé avec lui.

Le premier chapitre fournit des instructions pour un démarrage rapide et un petit tutoriel pour utiliser URBI sur le iRobot Create.

Le reste de la documentation contient une référence exhaustive pour le iRobot URBI engine et des exemples de script URBI plus avancés.

Chapter 2. Démarrage rapide

En premier, assurez vous que votre iRobot Create est opérationnel. Vous devriez jeter un oeil à : irobot.com/create si vous avez besoin d'aide pour cette étape...

Maintenant que vous avez un robot en état de marche vous pouvez installer le iRobot engine. La procédure d'installation dépendra de votre système, mais vous sera familière. Une fois que c'est fait, vous trouverez un répertoire bin dans lequel se trouve le binaire du urbi-server-irobot. D'autres fichiers importants sont localisés dans le répertoire data.

Avant de lancer l'engine, vous devrez changer la valeur system.comport dans le fichier data/config.u . Il doit avoir une valeur comme COM1 sur MS Windows, /dev/cu.SLAB_USBtoUART sur Mac OS X ou /dev/ttyUSB0 sur Linux. L'engine échouera si le port spécifié est incorrect ou n'a pas les bonnes permissions.

Allez dans votre répertoire d'installation iRobot, passez dans le répertoire bin et lancez urbi-server-irobot. Le message d'aide suivant apparaitra :

usage: ./urbi-server-irobot [options] period [path1 path2 ...]
  period : base URBI interval in milliseconds
les item path(chemin) sont des éléments absolus ou relatifs où l'on recherche dans l'ordre quand 'load' est appelé.
  options:
    -p port : précise le port tcp qu'URBI écoutera.
    -b address: lie à l'adresse ip spécifiée.
    -n      : n'autorise pas le travail en réseau.
    -r      : autorise le report du temps pris par la boucle URBI pour s'exécuter
    -s <period>: shell-mode (pas de réseau) avec une période donnée
    -f      : enable fast mode: le serveur tournera aussi vite que possible et émulera la période spécifiée

pour un lancement rapide du iRobot engine, tapez simplement :

./urbi-engine-irobot 50 ../data

L'engine affichera un header(en-tête) et dira que c'est prêt. Si tout va bien, rien de plus ne se produira. Si votre robot est éteint, ou injoignable, l'engine dira Waiting for robot initialisation.

Maintenant votre robot devrait fonctionner. Pour tester la connection, utilisez ou l'outil spécialement fournit par Gostai, ou un simple client telnet (notez que tout les URBI engine URBI ont le port 54000 par défaut).

telnet localhost 54000

S'il n'y a pas d'erreurs, votre client telnet devrait recevoir le même type d'en-tête que vous avez vu dans le engine window. La dernière ligne donnera votre id de connection et sera de la forme :

[65000000:ident] *** ID: U135766920
[65000011:notag] *** Connected to robot

Si ce n'est pas le cas, assurez vous que vous avez correctement installé l'engine et suivez les étapes suivantes. référez vous à Dépannage et FAQ si vous avez encore des difficultés pour lancer le serveur.

Vous êtes maintenant prêt à envoyer des commandes à votre robot par le iRobot URBI engine. Par exemple essayez :

vars;
...
[00004004:notag] *** ledPlay = OBJ
...

La première ligne demande pour toutes les variables connues par le serveur et les lignes suivantes, dont vous n'avez pas à vous inquiéter pour l'instant, liste les symboles et leurs valeurs respectives.

Chapter 3. Premières commandes

Préface

Ce chapitre introduira des concepts de base pour l'utilisation du iRobot Create URBI engine. Il peut être passé si vous êtes déjà familier avec les URBI engines.

Pour de plus amples instructions et informations sur les commandes URBI, lisez le premier chapitre du tutoriel URBI .

Avant tout autre chose, assurez vous du succès des étapes présentées dans le chapitre Démarrage rapide.

Liste rapide des périphériques

Voici une liste rapide des périphériques disponible pour le iRobot Create avec lesquels vous pouvez contrôler l'engine.

Si vous regarder attentivement aux fichiers groups.u et aliases.u fournit avec le URBI engine, vous verrez comment ces périphériques sont groupés et aliasés pour un accès simple et direct.

Table 3.1. caractéristiques des périphériques

NomTypeDescription
batterySensorEtat de la batterie (charge, courant...)
bumperLSensorpare-choc gauche
bumperRSensorpare-choc droit
buttonASensorbouton d'avance
buttonPSensorbouton play
cargobaySensor/ActorExtra I/O
cliffsensorLSensorcapteur cliff gauche
cliffsensorFLSensorCapteur cliff avant gauche
cliffsensorFRSensorCapteur cliff avant droit
cliffsensorRSensorcapteur cliff droit
commandActorinterface de commande
irSensorRécepteur d'Infrarouges
ledAdvanceActorled du bouton d'avance
ledPlayActorLed du bouton play
ledPowerActorLed du bouton power
lsd0ActorLow Side Driver 0
lsd1ActorLow Side Driver 1
lsd2ActorLow Side Driver 2
odometrySensorOdometry wrapper
speakerActorHaut-parleur du robot
virtualwallSensordétecteur de mur virtuel
wallSensordétecteur de mur
wheelFActorRoue avant
wheelLActorRoue gauche
wheelRActorRoue droite


Des commandes simples

Essayez cette première commande dans votre cession telnet :

ledPlay;
[00000476:notag] 0.000000

La première ligne demande la valeur de la led du bouton play. La seconde est la réponse du iRobot engine. La première valeur integer est un timestamp(marqueur temporel) pour la réponse (en millisecondes depuis le démarrage de l'engine). Elle est suivie d'un tag. Référez vous au tutoriel URBI pour plus de détails. Ce qui est important ici c'est la virgule flottante finissant la ligne. C'est la valeur stockée dans l'objet led. Ici 0.000000 indique que la led est éteinte. Donner la valeur 1 allumera la led.

N'oubliez pas le ';' à la fin de vos commandes. Le serveur URBI attendra indéfiniment pour la commande à attendre si vous l'oubliez.

Les commandes suivantes introduiront la notion de +end. Inclure vos commandes dans +end:{...};. Vous fera prévenir de la fin d'une commande par l'engine.

Essayez ce qui suit :

+end:{wheels = 100 time:2s | wait (2s) | wheels = 0;};
[00002622:notag] *** end

wheels est un groupe de périphériques pour les roues droite et gauche du robot. Votre robot accélérera jusqu'à 100 mm/s en 2 secondes, et avancera tout droit en maintenant cette vitesse pendant 2 secondes supplémentaires. Puis le robot s'arrêtera.

Vous devez maintenant essayer de le faire revenir à sa position initiale avec une commande similaire.

Ensuite, essayez ceci :

+end:{wheelL = -150 & wheelR = 150 | wait (2s) | wheels = 0;};
[00005095:notag] *** end

Votre robot tournera sur lui même pendant 2 secondes. Cette commande dit au robot de régler en même temps la vitesse de ses deux roues, puis d'attendre 2 secondes avant de s'arrêter complètement.

La dernière commande simple sera :

bumpRDetect:at (bumperR != 0) echo "Collision on right side";

Maintenant essayez de presser le bouton avant droit de votre iRobot. Vous obtiendrez un message du genre :

[00008215:notag] *** Collision on right side

Le mot-clé at vous permet de détecter des événements et de faire agir votre iRobot Create en conséquence. Le bumpRDetect: est appelé tag. Il est utilisé pour donner un nom, ou un identifiant à une commande. Vous pouvez utiliser des commandes spéciales comme stop, freeze and unfreeze pour manipuler les commandes en cours d'exécution. Essayez freeze bumpRDetect;. Le message précédent ne sera plus affiché quand bumper est pressé. La même commande avec unfreeze la rendra à nouveau opérationnelle..

Vous devriez à présent être capable de jouer avec votre iRobot URBI engine. Le chapitre suivant vous donnera des détails complets à propos de l'engine, mais ce que nous avons vu ici est suffisant pour utiliser le iRobot et URBI.

Une fois de plus, vous pouvez consulter le tutoriel complet d'URBI à le tutoriel.

Chapter 4. irobot-create.devices

Préface

Ce chapitre listera tous les objets (UObjects) définis par le iRobot Create URBI engine. C'est une liste complète donnant seulement les attributs principaux ou les méthodes de ces objets ou périphériques.

Dans chaque cas, tapez le nom du périphérique dans une connection au serveur URBI affichera la liste complète des attributs (vous aurez besoin de taper unalias dev si un périphérique particulier est aliasé).

Chaque périphérique et attribut décrit dans iRobot Create Open Interface Specification sera accessible à partir du URBI engine.

Notez s'il vous plaît que le fichier config.u a une ligne system.aliasmode = 1;. Quand la valeur n'est pas 0, plus d'alias sont définis dans aliases.u. Dans ce qui suit nous considèrerons que c'est le cas.

Motors

Deux moteurs sont définis, wheelL, wheelR. Ils sont groupés dans wheels pour un accès plus rapide lorsque la vitesse fixée est la même pour les deux roues.

La vitesse des roues va de -500mm/s à 500mm/s.

Chaque moteur est aliasé à son attribut .val. Cet attribut donne la vitesse actuelle en mm/s :

  wheelL = 10; 

est équivalent à

  wheelL.val = 10;

L'attribut drop mémorise l'état actuel des roues. C'est 0 si la roue est sur le sol, 1 si la roue n'est pas en contact avec le sol.

Sensors

Par défaut, tous les capteurs sont aliasés à leur attribut .val.

Les capteurs sont groupés par type dans les groupes buttons, walls, cliffs et bumpers. Ils sont aussi tous groupés dans le groupe sensors.

Gardez en mémoire que les groupes et les alias sont ici pour simplifier l'accès aux informations les plus utiles des périphériques. Vous devrez apporter de légères modifications aux fichiers aliases.u et groups.u pour adapter l'agencement des périphérique du robot à votre usage personnel.

Bumpers

Bumpers bumperL et bumperR sont des périphériques d'entrée placés sur le devant et les côtés du iRobot Create.

Ils ont la valeur 1 si appuyés, 0 autrement.

Wall Detector

Le détecteur de mur dépend de l'objet wall.

Sa valeur dépends de la façon dont le mur est détecté et ne fait pas référence à la distance. Un mur noir aura un signal plus faible qu'un mur blanc même s'il est détecté à la même distance.

Virtual Wall Detector

Le détecteur de mur virtuel dépend de l'objet virtualwall.

Sa valeur est définie à 1 si un mur virtuel est détecté, 0 autrement.

Cliff Detectors

Les détecteurs de vide sont respectivement appelés cliffSensorL, cliffSensorFL, cliffSensorFR, cliffSensorR dépendant de leur position sur le robot (gauche, avant gauche, avant droite, droite).

Leurs valeurs détectent les surfaces en dessous du robot. 0 il y a du sol, 1 est dans le cas d'une chute possible.

Les cliff detectors sont groupés dans cliffs.

L'attribut signal donne une valeur utile pour déterminer la distance entre le capteur et le sol.

Battery

Le périphérique batterie est appelé battery.

L'objet battery donne les informations suivantes à propos de la batterie du iRobot. L'attribut charge en mAh, l'estimation de la batterie et l'attribut capacity en mAh. L'attribut temperatureinterne de la batterie et son attribut source d'alimentation (none(aucun), power station ou adapter).

Il indique aussi le voltage actuel de la batterie en mV et son courant (val ou current) en mA.

State indique si la batterie est en charge.

Buttons

Les périphériques boutons sont appelés buttonP pour le bouton play et buttonA pour le bouton advance.

Les valeurs de Button sont 1 quand appuyé, 0 autrement.

Speaker

Le périphérique speaker(haut-parleur) est utilisé pour produire des notes de musique.

Une fois que la musique est rangée dans le speaker, un appel à sa méthode play() produira des notes.

Les commandes suivantes :

speaker = [69,60,73,32];
speaker.play();

jouera la note 69 : LA (440Htz) avec une longueur de 1s (60/60s) et la note 73 : DO# (554.4Htz) pour à peu près la moitié d'une seconde (32/60s).

La liste complète du code des notes est donné dans iRobot Create Open Interface Specification

La liste donnée de valeur de speaker ou speaker.val est une succession de couples note / duration composant une chanson. Les durées de note sont données en 60ème de seconde.

Les chansons peuvent seulement être de 16 notes.

La commande speaker.play() retourne immédiatement. Si vous lancez une nouvelle chanson alors qu'une chanson se joue encore, la commande sera ignorée.

Command

L'UObject command n'est pas un périphérique réel. C'est une interface logiciel utilisée pour envoyer des commandes directement à un iRobot Create.

Cet objet propose de modifier l'attribut de mode du robot. Alors que le mode Full est utilisé la plupart du temps, vous aurez besoin de basculer au mode Safe ou tout autre mode définit dans iRobot Create Open Interface Specification

command peut aussi être utilisé pour gérer la demo intégrée avec command.launchDemo(id) (lance la démo avec le id donné) et command.stopDemo() (arrête la démo en cours, identique à lancer une démo avec id -1).

Cet objet a aussi des méthodes pour envoyer et recevoir des données directement au iRobot Create : command.send(byte_list) et command.request(byte_list, answer_size)

Par exemple :

command.send([136, 1]);

lancera la démo 1 de create.

Et :

command.request([142,8], 1); 

retournera l'information du capteur wall detector.

Ces fonctions peuvent être utilisées pour accéder à chaque périphérique ou dispositif spécifié dans iRobot Create Open Interface Specification, et aux fonctionnalités que vous ajouterez à votre robot.

Notez que

  • Integers in list are in [|0, 255|]
  • La taille de la réponse attendue doit être exacte.
  • [] (liste vide) est retournée quand la requête échoue.

Ces commandes sont prévues pour les utilisateurs experts. Si vous êtes nouveau avec URBI ou iRobot Create, les périphériques et méthodes standards fournirons l'accès à tous ce que vous avez besoin.

Référez vous à iRobot Create Open Interface Specification afin d'obtenir les codes des commandes et les valeurs de retour expectées.

Odometry

L'UObject odometry est un périphérique spécial qui saisie la position du iRobot Create dans son environnement.

Dans la variable odometry sont stockés :

  • la distance (val en mm) que le Create a parcouru depuis le lancement du serveur
  • l'angle de rotation parcouru depuis le lancement du serveur
  • Les derniers radius, angle et velocity requis

Vous pouvez utiliser la fonction odometry.move(velocity, radius) pour contrôler votre robot. C'est un accès direct à la commande 137 dans le protocole iRobot.

 odometry.move(40, -200); 

Cet exemple fera se déplacer votre robot à une vitesse globale de 40 mm/s et tourner vers la droite en parcourant un arc de cercle de radiant 200;

Chapter 5. Exemples de fonctions avec URBI

Préface

Ce chapitre décrit les fonctions de base fournies avec le iRobot engine.

Vous pouvez accéder à leurs codes sources dans le répertoire data fourni avec l'engine. Vous êtes libre de les utiliser pour construire des comportements avancés pour votre iRobot Create.

Fonctions de déplacement

Ces premières fonctions sont utilisées pour faire bouger votre robot. Le support de l'odiométrie doit encore être amélioré, aussi, si elles sont bien utilisées, les fonctions basées sur le temps sont plus précises pour le moment.

Basée sur l'odométrie

Les fonctions func.rotateAngleOdo (angleNeeded, velocity) et func.moveStraightOdo (distance, velocity) font bouger le robot en se basant sur les informations d'odométrie envoyées par le robot.

La fonction func.rotateAngleOdo fait tourner le robot sur lui-même d'un angle donné, à une vitesse donnée.

La fonction func.moveStraightOdo fait suivre un ligne droite au robot à une vitesse donnée sur une distance donnée.

Si speed(vitesse) est différent de 0, le robot bouge. Sinon, il attends de l'odometrie, la valeur attendue.

Comme précisé précédement, ces fonctions peuvent ne pas être précises, dépendant de la façon dont vous utilisez votre serveur URBI. Une période de 100ms ne donne pas de si mauvais résultats.

Basée sur le temps

Les fonction suivantes func.rotateAngleTime (angle, radius, velocity, go) et function func.moveStraighTime (distance, velocity, go) font bouger le robot en se basant sur le temps théorique nécessaire pour exécuter le mouvement.

Notez que dans cette implémentation, func.rotateAngleTime permet de définir l'angle de rotation.

L'argument go active le mouvement. si 0 est donné, la fonction retourne le temps à attendre en ms pour finir le mouvement. Si ce n'est pas 0 qui est donné, le robot bouge effectivement avant le temps qui est retourné.

Cette mise en œuvre s'est avérée plus précise que la précédente. Mais notez qu'il ne l'est que dans de bonnes conditions, c'est-à-dire que l'interaction extérieur avec les roues ne sera pas prise en compte.

Fonctions de démonstration

Les démos intégrées

La fonction func.demo(demoId, duration) donne accès aux démos intégrées.

Cette mise en œuvre permet de régler une tempo de démonstration. Si duration est différente de 0, la demo est arrêtée après un temps donné d'exécution. Si duration est de 0, La demo tournera indéfiniment.

Notez que lancer une demo met le robot en mode Passive, vous pouvez le remettre à Full en fin de demo.

demos simples

La fonction supplémentaire func.blinkingLeds (factor, loops) joue une petite demo utilisant les leds du robot.

Le factor change la durée de la demo dans1/factor second,` et la demo tourne pendant loops cycles.

Chapter 6. Dépannage et FAQ

Ce chapitre n'est pas encore fini.

Dépannage

Questions fréquemments demandées

La FAQ pour URBI iRobot Create engine peut être consultée à : www.gostai.com/irobot_faq.html.

Vous serez aussi intéressé de parcourir notre forum à : forum.gostai.com/

Appendix A. Copyright


THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE
TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR
"LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE
LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE
OR COPYRIGHT LAW IS PROHIBITED.

BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND
AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS
YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF
SUCH TERMS AND CONDITIONS.

1. Definitions

   1. "Collective Work" means a work, such as a periodical issue,
   anthology or encyclopedia, in which the Work in its entirety in
   unmodified form, along with a number of other contributions,
   constituting separate and independent works in themselves, are
   assembled into a collective whole. A work that constitutes a
   Collective Work will not be considered a Derivative Work (as
   defined below) for the purposes of this License.  2. "Derivative
   Work" means a work based upon the Work or upon the Work and other
   pre-existing works, such as a translation, musical arrangement,
   dramatization, fictionalization, motion picture version, sound
   recording, art reproduction, abridgment, condensation, or any other
   form in which the Work may be recast, transformed, or adapted,
   except that a work that constitutes a Collective Work will not be
   considered a Derivative Work for the purpose of this License. For
   the avoidance of doubt, where the Work is a musical composition or
   sound recording, the synchronization of the Work in timed-relation
   with a moving image ("synching") will be considered a Derivative
   Work for the purpose of this License.  3. "Licensor" means the
   individual or entity that offers the Work under the terms of this
   License.  4. "Original Author" means the individual or entity who
   created the Work.  5. "Work" means the copyrightable work of
   authorship offered under the terms of this License.  6. "You" means
   an individual or entity exercising rights under this License who
   has not previously violated the terms of this License with respect
   to the Work, or who has received express permission from the
   Licensor to exercise rights under this License despite a previous
   violation.

2. Fair Use Rights. Nothing in this license is intended to reduce,
limit, or restrict any rights arising from fair use, first sale or
other limitations on the exclusive rights of the copyright owner under
copyright law or other applicable laws.

3. License Grant. Subject to the terms and conditions of this License,
Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
perpetual (for the duration of the applicable copyright) license to
exercise the rights in the Work as stated below:

   1. to reproduce the Work, to incorporate the Work into one or more
   Collective Works, and to reproduce the Work as incorporated in the
   Collective Works; 2. to distribute copies or phonorecords of,
   display publicly, perform publicly, and perform publicly by means
   of a digital audio transmission the Work including as incorporated
   in Collective Works;

The above rights may be exercised in all media and formats whether now
known or hereafter devised. The above rights include the right to make
such modifications as are technically necessary to exercise the rights
in other media and formats, but otherwise you have no rights to make
Derivative Works. All rights not expressly granted by Licensor are
hereby reserved, including but not limited to the rights set forth in
Sections 4(d) and 4(e).

4. Restrictions.The license granted in Section 3 above is expressly
made subject to and limited by the following restrictions:

   1. You may distribute, publicly display, publicly perform, or
   publicly digitally perform the Work only under the terms of this
   License, and You must include a copy of, or the Uniform Resource
   Identifier for, this License with every copy or phonorecord of the
   Work You distribute, publicly display, publicly perform, or
   publicly digitally perform. You may not offer or impose any terms
   on the Work that alter or restrict the terms of this License or the
   recipients' exercise of the rights granted hereunder. You may not
   sublicense the Work. You must keep intact all notices that refer to
   this License and to the disclaimer of warranties. You may not
   distribute, publicly display, publicly perform, or publicly
   digitally perform the Work with any technological measures that
   control access or use of the Work in a manner inconsistent with the
   terms of this License Agreement. The above applies to the Work as
   incorporated in a Collective Work, but this does not require the
   Collective Work apart from the Work itself to be made subject to
   the terms of this License. If You create a Collective Work, upon
   notice from any Licensor You must, to the extent practicable,
   remove from the Collective Work any reference to such Licensor or
   the Original Author, as requested.  2. You may not exercise any of
   the rights granted to You in Section 3 above in any manner that is
   primarily intended for or directed toward commercial advantage or
   private monetary compensation. The exchange of the Work for other
   copyrighted works by means of digital file-sharing or otherwise
   shall not be considered to be intended for or directed toward
   commercial advantage or private monetary compensation, provided
   there is no payment of any monetary compensation in connection with
   the exchange of copyrighted works.  3. If you distribute, publicly
   display, publicly perform, or publicly digitally perform the Work,
   You must keep intact all copyright notices for the Work and give
   the Original Author credit reasonable to the medium or means You
   are utilizing by conveying the name (or pseudonym if applicable) of
   the Original Author if supplied; the title of the Work if supplied;
   and to the extent reasonably practicable, the Uniform Resource
   Identifier, if any, that Licensor specifies to be associated with
   the Work, unless such URI does not refer to the copyright notice or
   licensing information for the Work. Such credit may be implemented
   in any reasonable manner; provided, however, that in the case of a
   Collective Work, at a minimum such credit will appear where any
   other comparable authorship credit appears and in a manner at least
   as prominent as such other comparable authorship credit.  4.

      For the avoidance of doubt, where the Work is a musical
         composition: 1. Performance Royalties Under Blanket
         Licenses. Licensor reserves the exclusive right to collect,
         whether individually or via a performance rights society
         (e.g. ASCAP, BMI, SESAC), royalties for the public
         performance or public digital performance (e.g. webcast) of
         the Work if that performance is primarily intended for or
         directed toward commercial advantage or private monetary
         compensation.  2. Mechanical Rights and Statutory
         Royalties. Licensor reserves the exclusive right to collect,
         whether individually or via a music rights agency or
         designated agent (e.g. Harry Fox Agency), royalties for any
         phonorecord You create from the Work ("cover version") and
         distribute, subject to the compulsory license created by 17
         USC Section 115 of the US Copyright Act (or the equivalent in
         other jurisdictions), if Your distribution of such cover
         version is primarily intended for or directed toward
         commercial advantage or private monetary compensation.
         5. Webcasting Rights and Statutory Royalties. For the
         avoidance of doubt, where the Work is a sound recording,
         Licensor reserves the exclusive right to collect, whether
         individually or via a performance-rights society
         (e.g. SoundExchange), royalties for the public digital
         performance (e.g. webcast) of the Work, subject to the
         compulsory license created by 17 USC Section 114 of the US
         Copyright Act (or the equivalent in other jurisdictions), if
         Your public digital performance is primarily intended for or
         directed toward commercial advantage or private monetary
         compensation.

5. Representations, Warranties and Disclaimer

UNLESS OTHERWISE MUTUALLY AGREED BY THE PARTIES IN WRITING, LICENSOR
OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR
OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE,
MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR
THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF
ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO
NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY
NOT APPLY TO YOU.

6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY
APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY
LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR
EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK,
EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

7. Termination

   1. This License and the rights granted hereunder will terminate
   automatically upon any breach by You of the terms of this
   License. Individuals or entities who have received Collective Works
   from You under this License, however, will not have their licenses
   terminated provided such individuals or entities remain in full
   compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
   survive any termination of this License.  2. Subject to the above
   terms and conditions, the license granted here is perpetual (for
   the duration of the applicable copyright in the
   Work). Notwithstanding the above, Licensor reserves the right to
   release the Work under different license terms or to stop
   distributing the Work at any time; provided, however that any such
   election will not serve to withdraw this License (or any other
   license that has been, or is required to be, granted under the
   terms of this License), and this License will continue in full
   force and effect unless terminated as stated above.

8. Miscellaneous

   1. Each time You distribute or publicly digitally perform the Work
   or a Collective Work, the Licensor offers to the recipient a
   license to the Work on the same terms and conditions as the license
   granted to You under this License.  2. If any provision of this
   License is invalid or unenforceable under applicable law, it shall
   not affect the validity or enforceability of the remainder of the
   terms of this License, and without further action by the parties to
   this agreement, such provision shall be reformed to the minimum
   extent necessary to make such provision valid and enforceable.
   3. No term or provision of this License shall be deemed waived and
   no breach consented to unless such waiver or consent shall be in
   writing and signed by the party to be charged with such waiver or
   consent.  4. This License constitutes the entire agreement between
   the parties with respect to the Work licensed here. There are no
   understandings, agreements or representations with respect to the
   Work not specified here. Licensor shall not be bound by any
   additional provisions that may appear in any communication from
   You. This License may not be modified without the mutual written
   agreement of the Licensor and You.