Copyright © 2006 Gostai
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
List of Tables
Cette documentation contient des informations pour le URBI engine du robot ePuck's. Dans l'état, les périphériques disponibles sont résumés ici. Vous trouverez également de nombreux tutoriels sur la façon d'utiliser l'agencement actuel, comment faire votre propre agencement et plus.
Ceci est un exemple simple qui explique comment utiliser le serveur URBI.
Dans le répertoire src , écrivez:
./epuck.exe 50 ../data COM6
Dans ce cas, un serveur URBI est créé.
Comme tout serveur, le port par défaut est 54000
et le path (chemin de répertoire) par défaut est .
et ../data.
Le dernier paramètre défini le port de connection,
ce peut être n'importe quel port de COM où le robot est relié.
Table of Contents
La documentation sur les périphériques suivants est écrite pour le URBI engine du ePuck.
L'UObject Wheel décrit un périphérique roue et contient les attributs suivants :
Table 3.1. Les attributs de Wheel :
| Nom | Description |
|---|---|
| id | identification de Wheel, il peut être "Left" ou "Right" |
| val | La vitesse de Wheel, de -1000 à 1000 |
| position | La position de Wheel, de -32000 à 32000. |
| init(id) | Le constructeur d'UObject.
Exemple: wheel = new Wheel("Left");
|
| reset() | Reset la position de Wheel à 0. Exemple: wheel.reset(); |
L'UObject Led décrit un périphérique led et contient les attributs suivants :
Table 3.2. Les attributs de Led :
| Nom | Description |
|---|---|
| id | identification de la Led, les valeurs peuvent être de 0 à 9. Chaque valeur réfère à une led différente. |
| val | L'état de la led. Il peut être 0 (off), 1 (on) ou 2 (switch). |
| init(id) | Le constructeur d'UObject.
Exemple: ledA = new Led(1); |
L'UObject Micro décrit un périphérique microphone et contient les attributs suivants :
Table 3.3. Les attributs du Sound sensor :
| Nom | Description |
|---|---|
| id | Une valeur d'identification, elle peut être "Left", "Right" ou "Back". |
| val | Le niveau du son mesuré. |
| init(id) | Le constructeur d'UObject.
Exemple: mic = new Micro("Back");
|
L'UObject Selector décrit le petit switch selector sur le dessus du robot et contient les attributs suivants :
Table 3.4. Les attributs du Selector :
| Nom | Description |
|---|---|
| val | La position courante du (peut être 0 à 15). |
| init() | Le constructeur d'UObject. Exemple: sel = new Selector(); |
L'UObject IR décrit les 8 périphériques infrarouges et contient les attributs suivants :
Table 3.5. Les attributs d'IR :
| Nom | Description |
|---|---|
| val | Les valeurs de proximité d'IR. C'est une liste de 8 valeurs correspondantes à 8 distances de proximité. |
| light | Les valeurs de lumière IR. C'est une liste de 8 valeurs correspondantes à 8 intensités lumineuses ambiantes. |
| init() | Le constructeur d'UObject. Exemple: infraRed = new IR(); |
L'UObject IR décrit les 3 périphériques accéléromètres et contient les attributs suivants :
Table 3.6. Les attributs d'Accelerometer :
| Nom | Description |
|---|---|
| val | Valeur de l'accélération verticale. |
| inclination | Valeur de l'inclinaison. |
| orientation | Valeur de l'orientation. |
| init() | Le constructeur d'UObject Exemple acc = new Acceleromter(); |
L'UObject Camera décrit le périphérique caméra et contient les attributs suivants :
Table 3.7. Les attributs de Camera :
| Nom | Description |
|---|---|
| val | L'image de la caméra. |
| zoom | La valeur du zoom. Par défaut, il est réglé à 8, mais il peut aussi être 4, 2 ou 1. |
| mode | La valeur du mode de camera. Par défaut, il est réglé à 1 (qui correspond à couleur), autrement il peut être à 0 (noir et blanc). |
| height | La valeur hauteur de camera. Par défaut, elle est réglé à 40, il n'est pas recommandé de toucher cette valeur ce qui cause une grande instabilité dans le robot. |
| width | La valeur largeur de camera. Par défaut, elle est réglé à 40, il n'est pas recommandé de toucher cette valeur ce qui cause une grande instabilité dans le robot. |
| init() | Le constructeur d'UObject Exemple c = new Camera(); |
L'UObject Colormap quand il est lié au périphérique camera fournit un détecteur de taches de base et contient les attributs suivants :
Table 3.8. Les attributs de colormap :
| Nom | Description |
|---|---|
| x | La position x du centre de gravité de la tache. |
| y | La position y du centre de gravité de la tache. |
| visible | Cette propriété est réglée à 1 quand la tache est visible. |
| ratio | Le ratio de la tache. |
| threshold | Le seuil de la tache. |
| orientation | l'orientation de la tache. |
| elongation | Alongement de la tache. |
| ymin | Valeur ymin de la couleur désirée. (Composante y de la couleur de la tache en YCbCr). |
| ymax | Valeur ymax de la couleur désirée. (Composante Y de la couleur de la tache en YCbCr). |
| cbmin | Valeur cbmin de la couleur désirée. (Composante Cb de la couleur de la tache en YCbCr). |
| cbmax | Valeur cbmax de la couleur désirée. (Composante Cb de la couleur de la tache en YCbCr). |
| crmin | Valeur crmin de la couleur désirée. (Composante Cr de la couleur de la tache en YCbCr). |
| crmax | Valeur crmax de la couleur désirée. (Composante Cr de la couleur de la tache en YCbCr). |
| init(source, ymin, ymax, cbmin, cbmax, crmin, crmax, threshold) | Le constructeur d'UObject
Exemple c = new Colormap("camera.val", 0, 255, 120, 190, 150, 230, 0.1););which detects a pink ball. |
L'UObject Speaker décrit le périphérique haut-parleur, vous autorisant à utiliser :
Table 3.9. Les méthodes de Speaker :
| Nom | Description |
|---|---|
| play(sound) | Jouer un son d'usage.
Exemple: Speaker.play("wow");
|
| stop() | appel de Exemple Speaker.stop(); |
L'UObject Command est conçu pour vous permettre d'utiliser des commandes spéciales :
Table 3.10. Les méthodes de Command :
| Nom | Description |
|---|---|
| reset() | Reset complètement le robot. Exemple: Command.reset(); . |
| stop() | Arrête le robot et éteint les leds. Exemple: Command.stop(); . |
| version() | imprime la version du firmware en cours. Exemple: Command.version(); . |
| calibrate() | Calibration du capteur IR. Exemple: Command.calibrate(); . |
Voici les différentes instances que nous avons choisi pour l'agencement en cours.
Table 3.11. Les caractéristiques de Servo
| Instance | UObject | Description |
|---|---|---|
| wheelL | Servo | Left wheel |
| wheelR | Servo | Right wheel |
| claw | Servo | Claw |
| sonar | UltraSoundSensor | Distance sensor |
| decibel | SoundSensor | Sound sensor |
| light | LightSensor | Light sensor |
| bumper | Switch | Touch sensor |
| beeper | Beeper | Emits beeps |
| battery | Battery | Battery |
Cette documentation présente comment utiliser l'engine avec l'agencement en usage chargé
(TriBot.ini).
Vous trouverez des informations utiles à propos d'URBI sur http://gostai.com/doc/urbi-tutorial.htm.
Trois moteurs sont disponibles, wheelL, wheelR et claw.
wheelL et wheelR sont groupés dans wheels.
Chaque moteur est aliasé à son attribut .torque.
aussi :
wheelL = 10;
égale
wheelL.torque = 10;
et
wheels = 10;
égale
wheelL = 10 & wheelR = 10;
L'attribut .torque vous autorise à régler la vitesse d'usage du moteur.
Cette valeur est réglée entre -100 et 100.
Aussi vous pouvez contrôler la vitesse des roues en tapant simplement :
wheels.torque = 100;
Une valeur négative inverse la rotation du moteur.
Vous pouvez lire la position du moteur (en degrés) en utilisant l'attribut .val.
Cette attribut est réglé à 0 quand vous mettez en route le robot. Aussi vous pouvez récupérer la
position d'usage de claw en tapant :
claw.val,
.
Dans le cas de claw ; nous avons ajouté un contrôle du PID, aussi vous pouvez régler une position.
claw.val = 360 ;
qui signifie que nous demandons une rotation entière du moteur de claw.
Change les paramètres de claw.PGain, claw.IGain et claw.DGain pour obtenir un contrôle
affiné de la position.
Tous les capteurs sont aussi aliasés à leur attribut .val, donc par exemple vous avez juste à demander bumper pour obtenir bumper.val. Cela marche de la même façon avec l'objet battery.
Les capteurs sont groupés dans le groupe sensors et tous les périphériques matériels (sensors + motors + battery + beeper) sont groupés dans le groupe hardware.
Le périphérique switch est appelé bumper dans notre agencement.
Vous pouvez demander sa valeur ( pour savoir si il est on ou off) en demandant
bumper.val ;
1 est bumper on, 0 est off.
Le capteur à ultrasons est appelé sonar.
Vous pouvez obtenir la distance lue en demandant l'attribut .val.
sonar.val ;
retourne la distance mesurée par le capteur. On aura en retour une valeur comprise entre 0 et 255 cm. Quand la valeur lue fait défaut, elle retourne 255.
Le capteur de son est appelé decibel dans notre agencement.
Vous pouvez obtenir la valeur lue en demandant l'attribut .val.
decibel.val ;
retourne une valeur normalisée entre 0 et 1. C'est une valeur brute proportionnelle à la quantité de décibels mesurés.
Vous pouvez régler le capteur de sons en deux modes différents en changeant l'attribut .mode.
Deux valeurs sont disponibles, "DB" et "DBA"
"DBA" est un mode ajusté mesurant seulement les fréquences comprises entre 200 et 14000Hz.
"DB" mesure une bande de fréquences étendue.
Règlez cette valeur en tapant :
decibel.mode = "DB" ;
.
La valeur par défaut est "DBA".
Le capteur de lumière est appelé light.
On récupère la valeur mesurée en demandant l'attribut .val.
light.val,
La valeur retournée est normalisée (entre 0 et 1) représentant un pourcentage de la quantité de lumière mesurée.
Vous pouvez régler le capteur de lumière en trois différents modes en changeant l'attribut .mode.
Les valeurs disponibles sont "Reflector", "Ambiant" et "Normal".
La valeur par défaut dans notre exemple est "Reflector".
"Reflector" signifie que le capteur de lumière allume sa led et mesure la lumière réfléchie.
"Ambiant" éteins la led et mesure la lumière ambiante.
"Normal" éteins la led et retourne la valeur brute mesurée.
Vous pouvez le changer en tapant :
light.mode = "Ambiant",
Le périphérique batterie est tout simplement appelé battery.
Vous pouvez obtenir la puissance d'usage en demandant l'attribut .val.
battery.val
Le périphérique bruiteur est appelé beeper.
Vous pouvez uniquement demander au beeper de jouer un son personnalisé, utilisez sa fonction :
play(frequency, time) ;
frequency est un integer entre 200 et 14000, qui est la fréquence du beep.
time est un integer mesuré en millisecondes, qui est la durée du son.
Si nous voulons jouer un son durant 1 seconde avec une fréquence de 200, nous ferons :
beeper.play(200, 1000),
Un temps de 0 est infini. De même la commande n'attends pas la fin du beep. Donc si vous voulez attendre jusqu'à la fin du beep, essayez quelque chose comme
{ beeper.play(myFrequency, myDuration) & wait(myDuration) },
L'UObject command n'est pas un périphérique. Il autorise l'envoie direct de commandes comme vous le faites avec le SDK du NXT. Vous trouverez plus d'informations sur http://mindstorms.lego.com/Overview/NXTreme.asp.
Vous ne pouvez pas créer d'instances Command mais utilisez le comme :
Command.send(myBuff) ;
myBuff est un buffer de command valide (liste d'integers entre 200 et 14000).
Command.send([3, 10, 10, 0 , 0]);
jouera un beep.
answer = Command.request(myBuff, size) ;
myBuff est un buffer de command valide (attendant une réponse).
size est la taille du buffer de retour (il doit être de la taille exacte, trop petit il bloquera tout le serveur, et trop grand il fera échouer votre requête).
answer est le buffer de retour (c'est une liste, [] est retourné quand la requête échoue).
Cette commande a été créée pour les utilisateurs experts qui demande plus d'URBI. IL n'est pas recommandée de l'utiliser si vous ne savez pas ce que vous faites et peut faire planter tout le serveur.
Utilisez le à vos propres responsabilités. Voici un exemple :
answer = Command.request([7,0], 15);
qui retourne les informations sur port d'entrée 1.
Table of Contents
Voici un exemple simple qui explique comment écrire votre propre agencement. Avant de le construire, vous devrez jeter un coup d'oeil au tutoriel URBI (http://www.gostai.com/doc/urbi-tutorial.htm).
Il y a 3 sortes de périphériques fournis par le serveur : moteurs, capteurs et autres périphériques.
Il y a un type de moteur appelé Servo.
Il y a 4 types de capteurs: Switch, SoundSensor, UltraSonicSensoret LightSensor.
2 autres périphériques sont disponibles: Battery et Beeper.
Ecrire un agencement consiste simplement à instancer des objets périphériques à partir des classes de base ci dessus. Nous allons maintenant vous montrer comment le faire :
Le constructeur d'initialisation de Servo a la syntaxe suivante:
myServoObject = new Servo(myPort);
Vous pouvez créer 3 objets Servo différents lié aux 3 différents ports ("A","B" et "C" ).
Dans le TriBot.ini en cours, nous créons nos objets Servo :
wheelL = new Servo("C");
wheelR = new Servo("A");
claw = new Servo("B");
La roue gauche est sur le port C, la roue droite sur le A et la pince sur le port B.
Le PID contrôle étant fournis avec ce moteur, vous pouvez le lier à un objet
Servo approprié pour le contrôler par la position.
Utiliser la syntaxe suivante pour lier le contrôle du PID.
myServoObject inherits PID;
Puis réglez vos propres paramètres de PID :
myServoObject.PGain = 0.01;
myServoObject.IGain = 0.01;
myServoObject.DGain = 0.01;
myServoObject.precision = 0.01;
N'hésitez pas à changer ces paramètres pour changer le comportement de votre PID. Maintenant vous pouvez lancer le contrôle du PID par :
myServoObject.setPID("myServoObject.val", "myServoObject.torque");
Dans notre exemple, nous utilisons le PID de cette façon :
claw inherit PID;
claw.PGain = 0.01;
claw.IGain = 0.01;
claw.DGain = 0.01;
claw.precision = 0.00;
claw.setPID("claw.val", "claw.torque");
Qui signifie que le PID tourne en permanence, où claw.torque contrôle claw.val
(Nous récupérons une position sur claw.val , et la vitesse en dépendant est automatiquement réglée).
Le contrôle du PID s'arrêtera quand la précision que vous attendez est atteinte, si vous voulez autoriser un contrôle permanent, réglez la précision sur 0.
Maintenant vous pouvez créer vos objets capteurs.
Commençons avec l'objet Switch. Pour le créer suivez la syntaxe :
mySwitchObject = new Switch(myPort);
où myPort peut être 1, 2, 3 ou 4.
Dans notre exemple, nous voulons utiliser le switch comme un bumper branché sur le port 4, aussi nous faisons :
bumper = new Switch(4);
C'est exactement la même façon pour créer un objet UltraSonicSensor :
myUSSObject = new UltraSonicSensor(myPort);
myPort peut être 1, 2, 3 ou 4.
Vous pouvez voir dans notre TriBot.ini un capteur ultrasonic sur le port 2:
sonar = new UltraSonicSensor(2);
Maintenant nous allons créer un objet SoundSensor :
mySoundObject = new SoundSensor(myPort, myMode);
Comme d'habitude, myPort peut être 1, 2, 3 ou 4.
myMode définit le mode de fonctionnement du capteur. Il peut être
"DB" ou "DBA", signifiant "décibel" ou "décibel équilibré"
(le dernier enregistre les sons dans le spectre audible des fréquences 400-14000Hz).
Aussi dans l'exemple nous créons un capteur de son sur le port 1 en utilisant décibel adjusted:
decibel = new SoundSensor(1,"DBA");
Le dernier capteur est le LightSensor, vous pouvez le créer avec la ligne :
myLightObject = new LightSensor(myPort, myMode);
avec myPort dans 1, 2, 3 ou 4.
MyMode définit encore le mode de fonctionnement du capteur et il peut être "Ambiant"
(ici le capteur mesure la lumière ambiante), "Reflector"
(le capteur allume sa led et mesure la lumière réfléchie) et "Normal"
(le capteur retourne sa valeur brute).
Nous avons choisi d'utiliser le capteur de lumière en mode reflector sur le port 1 aussi nous faisons :
light = new LightSensor(3,"Reflector");
Maintenant nous pouvons ajouter deux autres périphériques à notre agencement.
Le périphérique Battery nous permet de lire le niveau de la batterie.
Tapez simplement :
myBattery = new Battery();
Nous le créons de cette façon :
battery = new Battery();
Le périphérique Beeper nous permet d'émettre des beeps personnalisés à partir du haut-parleur du NXT.
créons le :
myBeeper = new Beeper();
Nous créons le beeper dans l'exemple :
beeper = new Beeper();
Table of Contents
Une chose agréable qui rend la vie plus facile avec URBI est de coder des fonctions simples de haut niveau.
Cela vous permet de déplacer votre robot facilement juste en appelant ces fonctions.
On commence avec la fonction forward() qui fait avancer votre robot... en avant!
fonction global.forward()
{
wheels = 10;
},
Ici nous déclarons une fonction forward() de portée (scope) global.
Déclarer la fonction dans un scope (vous pouvez l'appeler comme vous voulez), l'autorise a la rendre visible à partir de n'importe quelle connection d'où vous l'exécutez.
wheels = 10; règle la vitesse des roues à 10.
Pour ne pas toujours appeler global.forward(), vous pouvez créer une classe global et y ranger dedans toutes vos méthodes et attributs :
class global
{
var defaultSpeed ;
var x ;
var y ;
function forward() ;
function randomMove() ;
} ;
function global.forward()
{
//définition de la fonction;
} ;
function global.randomMove()
{
//définition de la fonction ;
forward() ; //appelée sans global
} ;
Maintenant, nous pouvons améliorer ce code permettant une vitesse personnalisée. Voici une bonne façon de le faire:
global.defaultSpeed = 10;
function global.forward()
{
wheels = global.defaultSpeed;
},
Ici nous définissons une variable dans le scope global qui définissent la vitesse personnalisée. Cela vous permet de définir la vitesse à chaque fois que vous le voulez (très utile lors de tests sur votre propre programme).
Enfin, nous pouvons ajouter un timer à cette fonction, utile pour se déplacer durant une période de temps fixe:
global.defaultSpeed = 10;
function global.forward(timer)
{
wheels = global.defaultSpeed |
wait(timer)|
wheels = 0;
},
Ici nous ajoutons un paramètre timer qui est le temps voulu de rotation des roues.
La syntaxe wheels = global.defaultSpeed | wait(timer) exécute sequentiellement wheels = global.defaultSpeed PUIS wait(timer). Quand vous séparez un groupe d'un autre (e.g. : wheels = 0 - qui arrête les roues) utilisant le séparateur |, qui fait attendre l'instruction pour l'instruction précédente. Donc wheels = 0 sera exécuté APRES la fin du timer.
Aussi cet appel fait avancer le robot en avant pendant une seconde puis s'arrêter.
global.forward(1000),
Ce qui suit est un exemple venant du fichier std.u qui définit des fonctions de mouvement de base.
class global ;
global.defaultSpeed = 10;
function global.forward()
{
wheels = global.defaultSpeed;
},
function global.backward()
{
wheels = -global.defaultSpeed;
},
function global.turnleft()
{
wheelL = - global.defaultSpeed &
wheelR = global.defaultSpeed;
},
function global.turnright()
{
wheelR = - global.defaultSpeed &
wheelL = global.defaultSpeed;
},
Ici, nous allons voir comment créer une fonction qui va générer un déplacement au hasard du robot. Cette fonction sera utile pour la prochaine partie de notre didacticiel. Cette fonction est destinée à faire réagir le robot à un événement. Donc, l'idée est de faire un mouvement de recul, puis à changer la direction au hasard. Nous avons également besoin de 2 paramètres, une constante de temps, ce qui fera tourner le robot pendant ce laps de temps (Ce qui évitera de ne pas tourner assez ); Et une base de temps randomisée qui est le temps maximum de rotation qui sera généré. Voici le code :
function global.randomMoves(constantTime, randomTime)
{
{backward() & wait(2s)}
|
{
{if (random(2) == 1) left()
else right()
}
&
wait( (constantTime+random(randomTime))*100)
}
|
forward()
},
{backward() & wait(2s)}
Aussi en premier
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.