J'ai lu beaucoup de choses récemment sur l' architecture de subsomption et il y a plusieurs façons dont les gens semblent préconiser.
Par exemple, certaines personnes utilisent une variable globale "flag" pour qu'une tâche prenne le contrôle. D'autres utilisent le endTimeSlice()
et permettent à l'arbitre de vraiment choisir. Et je pense que c'est correct.
J'ai cette petite section de code RobotC sur laquelle je travaille pour un robot de suivi de ligne, mais je ne suis pas sûr de le faire correctement car actuellement, la méthode de suivi prendra toujours le pas sur la méthode de recherche. Le flux correct doit être que la recherche guide le robot vers la ligne en utilisant un chemin en spirale pour trouver la ligne. Une fois la ligne trouvée, la piste devrait prendre le relais.
task evade(){
if(SensorValue(forwardSonarSensor) > threshold){
//box the obstruction
}
}
task find(){
if(SensorValue(lightSensor) > threshold){
//spiral the robot
}
}
task track(){
if(SensorValue(lightSensor) < threshold){
//go straight
}else{
//execute turns to follow the line
}
}
task main(){
while(true){
StartTask(evade,9);
StartTask(track,8);
StartTask(find,7);
wait1Msec(250);
}
}
Je viens d'utiliser quelques commentaires ici plutôt que le code réel pour être bref. Mes déclarations if ne sont-elles pas assez bonnes comme conditions car lorsque le robot est hors ligne, il track()
prend le relais. Est-ce dû à la déclaration else dans la piste? Si oui, comment avoir track()
effectué des virages quand il perd la ligne sans prendre le relais du fourrage au début du programme?
la source
StartTask
sont-ils la priorité de la tâche? Est-ce que 9 va être la plus haute priorité? Dans ce cas, ne devrait pasfind
avoir plus de priorité quetrack
? En fait, la condition defind
et laelse
condition detrack
sont les mêmes. Donc, en tant qu'être humain, si la valeur du capteur est supérieure au seuil, que feriez-vous? Aller en spirale ou tourner pour ajuster la ligne?Réponses:
Avec l'architecture de subsomption, vous devez soigneusement concevoir vos comportements de telle sorte que si vous attribuez une
T
priorité de tâchen
, ceT
devrait être ce que le robot devrait faire si toutes les tâches de priorité supérieure à celles quin
sont ignorées.Ordonnons vos exemples de tâches, puis trouvons un moyen de les implémenter. Vos tâches sont
evade
,find
ettrack
.En général, vous voudriez que le robot suive une ligne. Cependant, s'il ne pouvait pas détecter la ligne, il devrait essayer de la trouver. Surtout, elle doit échapper aux obstacles. Cela nous donne l'ordre suivant:
evade
find
track
La raison
find
a une priorité plus élevée quetrack
celle que, comme je l'ai mentionné ci-dessus, voustrack
ne le feriez que sievade
et nefind
sont pas nécessaires. Si vous mettezfind
citrack
- dessous , cela signifie que vous commencez à suivre s'il n'y a pas d'obstacle, même si vous n'êtes pas sur la ligne.Voyons maintenant votre implémentation:
N'oubliez pas que nous avons accordé
find
une priorité plus élevée. Par conséquent, si le robot ne peut pas détecter lelightSensor
, il ira en spirale en essayant de trouver la ligne. Une fois qu'il le fait,track
intervient. Comme vous pouvez le voir, laelse
condition detrack
ne se produit jamais.Pendant que cela fonctionne, le robot se déplacerait très maladroitement. En fait, vous ne pouvez pas y faire grand-chose, compte tenu de la construction actuelle de votre robot.
Bien que j'aie déjà répondu à votre question, voici une simple amélioration de votre suivi de ligne:
Au lieu d'un capteur de lumière, utilisez-en deux;
ls_left
etls_right
. En utilisant (au moins) deux capteurs, vous pouvez comprendre si vous êtes totalement hors de la piste ou sur le point de sortir de la piste. Dans le deuxième cas, vous pouvez facilement vous tourner dans la bonne direction et vous remettre sur la bonne voie.Votre
find
tâche est similaire:Autrement dit, vous allez en spirale uniquement si vous ne ressentez rien du tout
Votre
track
tâche devient maintenant plus efficace:Évidemment, avec une matrice de capteurs de lumière, vous pouvez mieux juger à quel point vous sortez de la piste (c'est-à-dire avec quel angle) et mieux décider comment vous remettre sur la bonne voie (c'est-à-dire avec quelle vitesse angulaire).
la source
réponse courte; non, vous devez vraiment faire les choses un peu différemment.
réponse longue et incomplète; Permettez-moi de vous donner un code pseudo approprié pour robotC, qui vous met sur une meilleure voie. Tout d'abord, n'utilisez pas de tâches - ce n'est PAS à cela que servent les tâches robotC. Ils pourraient être faits pour fonctionner, peut-être, peut-être pas (et vous avez besoin de quelques changements pour même essayer).
il y a deux ou trois choses ici; la priorité devient inutile. Aussi agréable qu'il semble avoir des tâches dans robotC avec des priorités, elles ne sont pas un bon choix pour la mise en œuvre de subsomption selon mon expérience. Pour des raisons comme, les priorités ne sont pas toujours respectées, les tâches ne peuvent pas être interrompues (parfois), donc lorsqu'un événement de priorité plus élevée se produit, il ne réagira pas comme vous vous y attendez, robotC n'est que récemment rentré, donc des choses comme l'accès à un capteur de plus d'une tâche peut être risqué (problèmes de synchronisation I2C), et dans certains cas, ce n'est pas le cas (capteurs interrogés automatiquement).
Vous pouvez ajouter votre propre implémentation prioritaire à la boucle ci-dessus au fur et à mesure que les choses fonctionnent, mais elle n'est vraiment pas nécessaire pour les démarrages.
Votre commentaire "// box the obstruction" décrit un comportement balistique. Celles-ci sont un peu délicates à mettre en œuvre en utilisant le multitâche. La boucle simple que j'ai utilisée le rend beaucoup plus facile et meilleur pour les débutants / l'apprentissage.
L'autre chose que je vais vous laisser, c'est que la subsomption tout en étant soignée et appropriée pour beaucoup de choses, n'est pas un bon moyen de mettre en œuvre ce qui est mieux fait traditionnellement. En effet, la partie «éluder» peut être un bon candidat pour la subsomption, mais honnêtement, votre autre tâche devrait être appelée «GoOnAboutYourBusiness». Je dis cela parce que vous ne voulez probablement pas passer de la recherche au suivi avec subsomption. Gérez ceux avec des boucles de programmation traditionnelles. Avec un seul capteur, - la lumière est-elle plus sombre ou plus claire que la dernière boucle? s'il est devenu plus sombre (en supposant une ligne noire) continuez à tourner dans la même direction, s'il est devenu plus clair, tournez dans le sens inverse, s'il est resté le même, continuez tout droit. Vous devrez probablement ajouter un PID et utiliser une courbe de direction au lieu de simplement tourner à gauche et à droite pour être plus fluide.
Et oui, plusieurs capteurs aident. http://www.mindsensors.com/ - ouais, c'est moi dans le film actuellement (11/10/2012)
Mise à jour: code réel
Je vais essayer cela dans un petit moment, mais il compile et illustre ce que j'ai écrit ci-dessus:
la source