Comment attraper une turtle avec NetLogo ?

Résolu
geekat Messages postés 242 Statut Membre -  
geekat Messages postés 242 Statut Membre -
Bonjour,
Je cherche des connaisseurs en NetLogo.
J'ai dessiné un robot et des pastilles (qui sont des turtles de race différente) et le but est que le robot ramasse 3 pastilles.
Je ne vois pas comment faire.

Aidez-moi SVP

4 réponses

KX Messages postés 19031 Statut Modérateur 3 020
 
Bonjour,

Voici un début de code qui gère la plupart des règles que tu as exposé.


La flèche verte c'est le robot, sur l'image il porte 3 billes et les emmènes dans un "panier" rouge (on en voit un autre qui contient déjà 3 billes).

Il reste à coder la partie "intelligence" car pour l'instant les robots et les billes vont toujours droit devant eux (ce qui n'est pas très efficace).

Remarque : il y a 1 robot, 4 paniers, 20 billes, ces valeurs sont en dur dans le code mais tu devrais facilement pouvoir les mettre dans des paramètres de la simulation. De même pour la taille de l'écran, la vitesse du robot, le nombre de billes maximum à porter etc.
Avec Netlogo partout où tu peux mettre des paramètres c'est mieux de les rendre disponibles pour tester la simulation.

J'ai mis quelques commentaires, mais il n'y a rien de très compliqué.
J'ai juste utilisé une astuce : la bille sait si elle est libre (valeur -1 donc elle se déplace) ou si elle est attrapée (donc elle suit son propriétaire).

;;;;; DECLARATIONS

breed [ robots robot ]
robots-own [ robot-nb-billes ]

breed [paniers panier]
paniers-own [ panier-nb-billes ]

breed [ billes bille ]
billes-own [ bille-proprietaire ]

;;;;; INITIALISATION

to setup

  clear-all
  reset-ticks  
  set-patch-size 50
  resize-world 0 10 0 10
  
  ask patches [
     set pcolor (pxcor + pycor) mod 2
  ]
  
  create-robots 1
  [
    setxy random-xcor random-ycor
    set shape "default"
    set size 1
    set color green
    set robot-nb-billes 0
    set label robot-nb-billes
  ]

  create-paniers 4
  [
    setxy int(random-xcor) int(random-ycor)
    set shape "target"
    set size 1
    set color red
    set panier-nb-billes 0
    set label panier-nb-billes
  ]

  create-billes 20
  [
    setxy random-xcor random-ycor
    set shape "dot"
    set color blue
    set size 1
    set bille-proprietaire -1
  ]

end

;;;;; EVOLUTION

to go

  ; le robot se déplace
  ask robots
  [
    forward 1
  ]

  ; une bille qui n appartient à personne se fait attraper par un robot
  ask billes with [bille-proprietaire = -1 and any? robots-on patch-here] [
    let proprietaire -1
    ask robots-on patch-here [
      if robot-nb-billes < 3 and proprietaire = -1 [
        set proprietaire who
        set robot-nb-billes (robot-nb-billes + 1)
        set label robot-nb-billes
      ]
    ]
    set bille-proprietaire proprietaire
  ]
  
  ; le robot vide ses billes dans un panier s il en a un près de lui
  ask robots with [robot-nb-billes > 0 and any? paniers-on patch-here]
  [
      let robot-who who
      let nb-billes robot-nb-billes
      
      ; on choisit le panier 
      ask one-of paniers-on patch-here [
        
        let panier-who who
        
        ; on prend les billes du robot
        ask billes with [bille-proprietaire = robot-who] [
          set bille-proprietaire panier-who ; la bille passe du robot au panier
        ]
        
        ; on remplit le panier
        set panier-nb-billes (panier-nb-billes + nb-billes)
        set label panier-nb-billes
      ]
      
      ; on vide le robot
      set robot-nb-billes 0
      set label robot-nb-billes
  ]
  
  ; les billes attrapées restent avec leur proprietaire
  ask billes with [bille-proprietaire > -1]
  [
    let x 0
    let y 0
    
    ask turtle bille-proprietaire [
      set x xcor
      set y ycor
    ]
    
    set xcor x
    set ycor y    
  ]

  ; les billes non attrapées se déplacent
  ask billes with [bille-proprietaire = -1]
  [
    forward 0.5  
  ]
  
  ; si toutes les billes sont dans des paniers on s arrête
  if not any? billes with [bille-proprietaire = -1] and not any? robots with [robot-nb-billes > 0] [
     stop
  ]
  
  tick

end

Remarque : pour la visualisation de la simulation, il faut toujours choisir
view updates > on ticks
, ce qui redessine l'écran que lorsque l'on fait un
tick
dans le code, c'est à dire à la fin de chaque étape.
2
geekat Messages postés 242 Statut Membre
 
Waaw, merci beaucoup! très bon code! Il avale bien 3 :)
Que pense-tu de cette fonction search ? ça permet au robot de faire tourner à gacuhe à droite, mais si la bille est juste à côté, il peut quand même ne pas la voir
;;;;;;Au début
turtles-own
[
 time-since-last-found
]
end
;;;;Dans Go
to go
;;;;;
ask robots [search]   
to search 
  ifelse time-since-last-found <= 20
 [right (random 181) - 90]
 [right (random 21) - 10]
forward 1
end
end
0
KX Messages postés 19031 Statut Modérateur 3 020
 
J'en parlais déjà ici :
Remarque : tu ne donnes jamais de valeurs à time-since-last-found, il vaut donc toujours 0, de plus est-ce que tu en as vraiment pour toutes les tortues, ne serait-ce pas plutôt une propriété spécifique au robot seulement ?
Je rajouterais que cela n'est pas très intelligent vu que tu ne te sers pas de ta perception (angle de 40°) pour te diriger vers une bille ou un panier en particulier. Tu te déplaces au hasard donc ce n'est pas plus efficace que marcher droit devant toi. D'ailleurs c'est peut-être moins efficace vu qu'en ligne droite tu es sûr de toujours passer au dessus de chaque case, alors que là rien ne te le garantie.

De plus, en terme de code, tu ne peux pas imbriquer deux méthodes l'une dans l'autre, il faut d'abord terminer le to go avant de commencer le to search.

to go
    ask robots [search]   
end

to search 
    ifelse time-since-last-found <= 20
        [right (random 181) - 90]
        [right (random 21) - 10]
    forward 1
end
0
KX Messages postés 19031 Statut Modérateur 3 020
 
Bonsoir,

Quand tu dis ramasser, tu veux dire faire déplacer ton robot jusqu'à une pastille ? Et quel est ton code ?
0
geekat Messages postés 242 Statut Membre
 
Par ramasser je veux dire coller la pastille au robot, mais avant ça il faut qu'il la cherche.
Voici le code complet :

;;;;;; Nouvelle espèce de tortue ;;;;;;;;;;
breed [robots mon_robot]
breed [billes bille]

;;;;; Variable d’agent ;;;;;;;;;
turtles-own
[
time-since-last-found
]
;;;;; Setup = INITIALISATION ;;;;;;
to setup
clear-all
create-robots 1
[
setxy random-xcor random-ycor
]

create-billes 10
[
setxy random-xcor random-ycor
]
end

;;;;; Go = EVOLUTION DU SYSTEME : mvt ;;;;;
to go

ask robots
[
forward 1
set shape "mon_robot2"
set size 12

]

ask billes
[
forward 1
set shape "dot"
set size 3
]
ask robots[search]
ask robots [create-links-with other turtles]

end

to search
ifelse time-since-last-found <= 20
[right (random 181) - 90]
[right (random 21) - 10]
forward 1


end
0
KX Messages postés 19031 Statut Modérateur 3 020
 
Pour info, un "code complet" doit également contenir l'interface graphique c'est à dire la définition de tes boutons go/setup (tu pourrais en avoir beaucoup plus), mais également la forme de ton robot2, etc.
Tu obtiens tout ça (et plus) dans le fichier .nlogo quand tu fais "save as"

Peu importe, je les ai rajouté moi même, mais comme je n'ai pas ton image de robot, je l'ai remplacé par un papillon :-)

Par contre je n'ai toujours pas compris le but de ton programme. Pour l'instant tu as tes billes qui vont droit devant elles et le robot qui se déplace aléatoirement, ça ne m'aide pas beaucoup à comprendre ce que tu cherches à faire.

Quelques remarques quand même : la définition de la forme des tortues, leur taille, ou même les liens qu'il y a entre turtles, ça peut se faire qu'une seule fois, au moment du setup.
Lors du go tu dois juste marquer ce qui change d'une étape à l'autre (dans ton cas les déplacements), ça évite de faire des calculs inutiles à chaque tour.

;;;;;; Nouvelle espèce de tortue ;;;;;;;;;;

breed [robots robot]
breed [billes bille]

;;;;; Variable d’agent ;;;;;;;;;

turtles-own
[
  time-since-last-found
]

;;;;; Setup = INITIALISATION ;;;;;;

to setup

  clear-all

  create-billes 10
  [
    setxy random-xcor random-ycor
    set shape "dot"
    set size 3
  ]

  create-robots 1
  [
    setxy random-xcor random-ycor
    set shape "butterfly"
    set size 3
    create-links-with other turtles
  ]

end

;;;;; Go = EVOLUTION DU SYSTEME ;;;;;

to go

  ask robots
  [
    ; change direction
    ifelse time-since-last-found <= 20
      [right (random 181) - 90]
      [right (random 21) - 10]
    
    ; move
    forward 1
  ]

  ask billes
  [
    forward 1  
  ]

end

Remarque : tu ne donnes jamais de valeurs à time-since-last-found, il vaut donc toujours 0, de plus est-ce que tu en as vraiment pour toutes les tortues, ne serait-ce pas plutôt une propriété spécifique au robot seulement ?
0
geekat Messages postés 242 Statut Membre
 
Merci pour les explications!
Je pensais avoir défini le setup et go dans le code, pourquoi ce n'est pas complet ?
Par contre pour robot2, je suis d'accord. Mais comme c'est la première fois que j'utilise NeLogo, je ne sais pas où ces informations sont sauvegardées.

Le but de mon programme c'est que le robot doit déplacer les billes 3 par 3 dans un coin pour en faire un tas, les billes ramassées devraient changer de couleur pour faire la différence.
Merci beaucoup :)
0
geekat Messages postés 242 Statut Membre
 
Tu es sûr pour les liens ? parce qu'il n'apparaissent plus lorsque je les mets dans setup
0
KX Messages postés 19031 Statut Modérateur 3 020
 
Je pensais avoir défini le setup et go dans le code, pourquoi ce n'est pas complet ?
Tu as défini les fonctions setup et go dans le code, mais moi j'ai du rajouter les deux boutons setup et go qui sont dans l'interface graphique mais ne sont pas dans le code (mais c'est pas grave)

Quand on code avec Netlogo il y a une infinité de manière différentes de traiter un problème et de questions à se poser, qui peuvent te paraître bête, mais ça définit les "règles du jeu" pour que ta simulation fonctionne.

Je pose donc mes questions, j'en aurai peut-être d'autres :

1) est-ce que les billes sont censées être immobiles ? Parce que pour l'instant dans ton code elles se déplacent sans arrêt
2) le déplacement doit se faire 3 par 3, est-ce ça veut dire qu'il ne peut déplacer que 3 billes au maximum en même temps ?
3) est-ce que le robot "avale" la bille et la stocke comme un chargement, ou est-ce qu'il est obligé de les pousser, c'est à dire que les billes restent à côté du robot.
4) est-ce qu'une bille que le robot ne peut pas prendre est un obstacle pour le robot, est-ce qu'il doit les éviter ou il peut passer par dessus ?
5) tu dis qu'il doit les placer dans un coin, mais par défaut Netlogo travaille sur un tore (si tu vas à droite tu te retrouves à gauche, idem pour le haut et le bas), donc il n'y a pas de coin, mais si tu veux on peut limiter ton espace pour qu'il soit rectangulaire...
6) admettons qu'il y ait 4 coins, tu vas pouvoir faire 4 tas de 3 billes... mais tu en as 20, que se passe-t-il pour les 8 billes restantes ?
7) quand ton robot se déplace, est-ce qu'il a une connaissance absolue de tout l'espace de simulation ou il a une vision limitée ?
8) même question que pour la 3 : dans tes tas est-ce que les billes se superposent ou est-ce qu'elles sont nécessairement les unes à côté des autres ?
9) que fait ton robot une fois qu'il a fini de faire ses tas ?

Imagines la scène se dérouler dans ta tête, si tu vois d'autres règles à me décrire n'hésite pas, plus les règles sont précises plus le résultat sera proche de ce que tu attends.
0
geekat Messages postés 242 Statut Membre
 
Merci beaucoup!
J'aurais 2 questions :P :
1) Le logiciel Netlogo bug beaucoup chez moi, est-ce à cause de la modélisation ou à cause de mon ordinateur ?
2) J'aimerais ajouter un slide à la turte "robots", alors j'ai ajouté le bouton slider, je l'ai nommé "robots" mais j'ai cette erreur : There is already a variable called ROBOTS
Pour les slides, je ne sais pas quel code il faut écrire lorsqu'il s'agit de breed.
Quand je n'ai pas breed, je peux faire ce code qui marche :
; Création de la tortue 
crt tortue
[
 set size 3       
 set color yellow 
] 
; Le slide a le nom "tortue"
0
geekat Messages postés 242 Statut Membre
 
1) Précision : en fait c'est le Go avec Forever qui rame chez moi
0
KX Messages postés 19031 Statut Modérateur 3 020
 
1) Quel genre de bugs ? Personnellement je ne constate rien d'anormal avec le code que j'ai envoyé hier, mais j'utilise une vieille version (5.0.2), là pour tester je viens de télécharger la dernière version (5.2.1) mais pareil ça marche bien.
Je suis sous Windows 7 avec Java 8u60 installé.

2) Il faut toujours que les noms que tu choisissent soient différent,
robots
existe déjà, donc il faut un autre nom, de préférence explicite pour comprendre à quoi ça sert, par exemple je peux créer un slider
nombre-robots
et faire :
create-robots nombre-robots
0
KX Messages postés 19031 Statut Modérateur 3 020
 
Le Go avec Forever c'est ce que j'utilise, il peut-être assez gourmand si tu utilise la vue "continuous" puisqu'il va rafraîchir la fenêtre à chaque changement.
Mais comme je l'indiquais hier la vue "on ticks" est plus pertinente puisqu'elle affiche l'état de la simulation qu'une fois chaque étape terminée avec tous les changements d'un coup (donc moins souvent).

Remarque : tu peux également accélérer ou ralentir la simulation avec le slider du haut. En option avancée tu peux également regarder le bouton Settings et modifier le Frame Rate.
0
geekat Messages postés 242 Statut Membre
 
1) En fait ça bloque, ça fige l'image. Le bouton reste noir, le curseur tourne. J'utilise la version 5.2.0 windows7, java 8.0
2) Super! merci beaucoup, ça marche.
0
geekat Messages postés 242 Statut Membre
 
Merci!
Ah oui, je vais le changer en "on ticks"
J'ai un Frame Rate à 30, je ne sais pas à quoi ça correspond
0
geekat Messages postés 242 Statut Membre
 
Bonjour,
J'aurais une autre question si possible, sur ce même exercice : en fait, je devrais former un tas sans avoir de paniers et former un tas de billes non superposées. Comment faire ?
Merci
0
KX Messages postés 19031 Statut Modérateur 3 020
 
Bonjour,

Tu peux éventuellement considérer que les billes que tu attrapes tu ne les poses plus quand tu arrives sur un panier, mais que tu les poses quand tu es sur une case vide dont l'une des cases voisines contient déjà une bille posée.

Ça te ferait une bille par case (donc non superposée) et le tas serait formé par la contiguïté des cases où seraient ces billes.

Remarque : visuellement il faudrait que tes billes soient de la taille d'une case pour que cela soit cohérent. Donc plutôt avec une shape "circle" que "dot".
0
geekat Messages postés 242 Statut Membre > KX Messages postés 19031 Statut Modérateur
 
Merci pour ta réponse.
Je crois que "cricle" va être trop grand, si j'ai beaucoup de billes.

Je comprends pas comment on peut faire ces actions : attraper et poser. J'ai vu ton code qui fait ça, mais à partir de la ligne 66, je suis perdue :P, pour moi attraper c'est en une fois, mais apparemment pas du tout, il faut prévoir beaucoup de choses.
0
KX Messages postés 19031 Statut Modérateur 3 020
 
Je crois que "cricle" va être trop grand, si j'ai beaucoup de billes. "
La taille n'a pas d'importance, en réalité la turtle aura toujours la même taille qu'avant, c'est juste que le dessin de "dot" masque la moitié de la taille de la turtle alors que "circle" prends tout l'espace.

Si tu mets deux turtles "dot" l'une à côté de l'autre (sur deux patch contigüs) tu as l'impression qu'elles sont distantes :


Alors que les même turtles, de même taille, juste en changeant leur forme, semblent bien former un "tas" de deux billes :

Après, si ça te parait "grand" c'est peut-être parce que ton espace est trop petit, dans ce cas il faut augmenter les dimensions de l'espace, mais il faut que tes billes soient de la même taille que les patch, et ainsi travailler sur les espaces de voisinage.

J'ai vu ton code qui fait ça, mais à partir de la ligne 66, je suis perdue :P, pour moi attraper c'est en une fois, mais apparemment pas du tout, il faut prévoir beaucoup de choses.
Il y a une interaction entre les billes et le robot, si bien que le robot attrape une bille certes, mais la bille est aussi attrapée par le robot... En indiquant par quel robot elle a été attrapée on indique à la bille où elle doit se déplacer (c'est à dire au même endroit que le robot), sinon elle continuerait d'avancer toute seule, alors qu'elle est attrapée...

Je détailles si tu veux pour cette partie là (mais vu le nombre d'explications à donner pour chaque ligne, je te laisserais comprendre le reste tout seul...)

; une bille qui n appartient à personne se fait attraper par un robot
  ask billes with [bille-proprietaire = -1 and any? robots-on patch-here] [
    let proprietaire -1
    ask robots-on patch-here [
      if robot-nb-billes < 3 and proprietaire = -1 [
        set proprietaire who
        set robot-nb-billes (robot-nb-billes + 1)
        set label robot-nb-billes
      ]
    ]
    set bille-proprietaire proprietaire
  ]

Alors, ligne par ligne :
ask billes with [bille-proprietaire = -1 and any? robots-on patch-here]

Ici je "parle" à certaines billes en particulier (pas à toutes), uniquement celles dont la valeur
bille-proprietaire = -1
, c'est à dire qu'elles n'appartiennent à aucun robot et aucun panier (elles sont donc libres et peuvent être attrapées).
De plus avec
any? robots-on patch-here
je précise que les billes libres à laquelle je m'adresse sont uniquement celles qui ont un robot sur le même patch qu'elle.
Je ne dis donc pas que le robot attrape une bille, mais plutôt que la bille se fait attrapé par un robot qui se trouve au même endroit qu'elle (ce qui revient au même).

Vu la commande précédente, je parlais à toutes les billes qui étaient attrapables, maintenant je suis dans le contexte d'une de ces billes en particulier.

let proprietaire -1

Pas grand chose à dire ici, je configure une variable temporaire qui va me servir ensuite, elle correspond à la valeur actuelle de bille-proprietaire, c'est à dire -1.

ask robots-on patch-here [

Je suis toujours dans le contexte d'une bille attrapable, et je lui demande de parler aux robots qui sont sur la même case qu'elle (toi tu n'as qu'un seul robot, mais ce code est compatible pour un nombre quelconque de robots).

if robot-nb-billes < 3 and proprietaire = -1 [

Maintenant je suis dans le contexte du robot qui est à l'endroit de la bille attrapable.
Si ce robot a moins de 3 billes et que le propriétaire de la bille vaut -1 alors je fais :

set proprietaire who

Je dis à la bille qui est son propriétaire (who est l'identifiant du robot). Mais comme je suis dans le contexte du robot je passe cette information à la variable temporaire.

set robot-nb-billes (robot-nb-billes + 1)

Je dis au robot qu'il a une bille de plus.

set label robot-nb-billes

J'affiche le nouveau nombre de billes sur l'étiquette du robot (optionnel)

set bille-proprietaire proprietaire

Et enfin, quand je reviens dans le contexte de la bille, je peux lui définir son nouveau propriétaire, en lui donnant la valeur stockée dans la variable temporaire.
Remarque : ça peut très bien être encore -1 si le robot n'avait pas pu l'attraper (car il avait déjà 3 billes), dans ce cas la bille n'est toujours pas attrapée.
0
geekat Messages postés 242 Statut Membre
 
Merci beaucoup pour les explications :)
Pour déposer une turtle dans un panier, il faut tout ce code :
 ;le robot vide ses billes dans un panier s il en a un près de lui
  ask robots with [robot-nb-billes > 0 and any? paniers-on patch-here]
  [   
   let robot-who who
      let nb-billes robot-nb-billes
      
      ; on choisit le panier 
      ask one-of paniers-on patch-here [
        
        let panier-who who
        
        ; on prend les billes du robot
        ask billes with [bille-proprietaire = robot-who] [
          set bille-proprietaire panier-who ; la bille passe du robot au panier
          set color green
        ]
        
        ; on remplit le panier
        set panier-nb-billes (panier-nb-billes + nb-billes)
        set label panier-nb-billes
      ]
      
      ; on vide le robot
      set robot-nb-billes 0
      set label robot-nb-billes
  ]


Et si le panier était un patch, comme tu l'as montré dans les deux figures, dans ce cas il n'y a pas d'incrémentation . Comment as-tu déposé une turtle sur un patch ?
0
KX Messages postés 19031 Statut Modérateur 3 020
 
Je n'ai pas fait de code, j'ai juste bidouillé pour avoir le dessin pour montrer la différence entre dot et circle...

Cependant même si tu mets les billes les unes à côté des autres, je pense qu'il te faut quand même des paniers (ou équivalent), au moins un au départ pour savoir où poser la première bille du tas que tu vas former.

Un truc qui pourrait fonctionner, c'est d'attribuer une couleur (rouge par exemple) à toutes les cases qui peuvent accueillir des billes.
Donc le panier de départ est une case rouge. Et ensuite tu fais en sorte que si tu poses une bille sur une case rouge, celle-ci n'est plus rouge (elle ne peut plus recevoir de bille puisqu'elle en a déjà une) par contre toutes les cases voisines deviennent rouges (sauf si elles ont une bille aussi). Et en posant tes billes sur des cases rouges tu es sûr de former des tas.

Pour travailler avec les voisinages tu peux utiliser neighbors4.

Remarque : je parle de case rouge pour que ce soit visuel, mais tu peux rajouter n'importe quelle info non visuelle à ton patch pour faire la même chose...
0