Exemples: Vision
Cette page explique comment utiliser le set vision du Ned
Note
Même si vous n’avez pas de set vision, vous pouvez toujours faire ces exemples avec la version du simulateur Gazebo
Danger
Si vous utilisez un robot physique, assurez vous que son environnement ne présente pas d’obstacles
Bout de code nécessaire
Important
Dans le but de réaliser les exemples suivants, vous devez créer un workspace vision Dans cette page, le workspace utilisé est appelé workspace_1`.. Pour le créer, l’utilisateur devrait aller sur Niryo Studio !
Le début des exemples étant toujours pareil, ajoutez les lignes suivantes au début de vos codes
# Imports
from pyniryo import *
# - Constants
workspace_name = "workspace_1" # Robot's Workspace Name
robot_ip_address = "x.x.x.x"
# The pose from where the image processing happens
observation_pose = PoseObject(
x=0.16, y=0.0, z=0.35,
roll=0.0, pitch=1.57, yaw=0.0,
)
# Place pose
place_pose = PoseObject(
x=0.0, y=-0.2, z=0.12,
roll=0.0, pitch=1.57, yaw=-1.57
)
# - Initialization
# Connect to robot
robot = NiryoRobot(robot_ip_address)
# Calibrate robot if robot needs calibration
robot.arm.calibrate_auto()
# Updating tool
robot.tool.update_tool()
# --- -------------- --- #
# --- CODE GOES HERE --- #
# --- -------------- --- #
robot.end()
Indication
Tous les exemples qui suivent sont une petite partie de ce qui peut être réalisé avec l’API en termes de vision. Nous vous conseillons de regarder API - Vision pour comprendre plus en profondeur
Simple Pick & Place par Vision
Le but d’un Pick & Place par Vision est le même qu’un Pick & Place classique, avec une légère différence : le robot détecte où le robot doit aller pour saisir !
Ce court exemple montre comment réaliser votre première saisie par vision en utilisant la fonction vision_pick()
:
robot.move_pose(observation_pose)
# Trying to pick target using camera
obj_found, shape_ret, color_ret = robot.vision.vision_pick(workspace_name)
if obj_found:
robot.pick_place.place_from_pose(place_pose)
robot.arm.set_learning_mode(True)
Détails de code - Simple Pick and Place par Vision
Pour réaliser une saisie par vision, vous devez vous mettre dans une position où le robot peut voir le workspace
robot.arm.move_pose(observation_pose)
Ensuite, nous essayons de réaliser un pick par vision dans le workspace avec la fonction vision_pick()
obj_found, shape_ret, color_ret = robot.vision.vision_pick(workspace_name)
Les variables shape_ret
et color_ret
sont respectivement du type ObjectShape
et ObjectColor
, et stocke la forme et la couleur de l’objet détecté ! Nous ne les utiliserons pas pour ce premier exemple.
La variable obj_found
est un booléen qui indique si un objet a été trouvé et saisie, ou non. Ainsi, si la saisie a fonctionné, on peut aller déposer l’objet à la position de dépôt.
if obj_found:
robot.pick_place.place_from_pose(place_pose)
Enfin, on désactive le couple des moteurs.
robot.arm.set_learning_mode(True)
Note
Si votre variable obj_found
indique Faux
, regarde ça :
Rien n’obstrue le champ de vision de la caméra
Les 4 marqueurs du workspace sont visibles
Au moins 1 objet est entièrement placé à l’intérieur du workspace
Premier conditionnement par la vision
Dans la plus part des cas d’usage, robot devra réaliser plus d’un Pick & Place. Dans cet exemple, nous verrons comment conditionner plusieurs objets selon une ligne droite
# Initializing variables
offset_size = 0.05
max_catch_count = 4
# Loop until enough objects have been caught
catch_count = 0
while catch_count < max_catch_count:
# Moving to observation pose
robot.arm.move_pose(observation_pose)
# Trying to get object via Vision Pick
obj_found, shape, color = robot.vision.vision_pick(workspace_name)
if not obj_found:
robot.wait(0.1)
continue
# Calculate place pose and going to place the object
next_place_pose = place_pose.copy_with_offsets(x_offset=catch_count * offset_size)
robot.pick_place.place_from_pose(next_place_pose)
catch_count += 1
robot.arm.go_to_sleep()
Détails de code - Premier conditionnement par vision
On veut attraper max_catch_count
objets, et de les séparer de offset_size
mètre
offset_size = 0.05
max_catch_count = 4
On démarre une boucle jusqu’à ce qu’on attrape max_catch_count
objets
catch_count = 0
while catch_count < max_catch_count:
Pour chaque itération, on se rend dans un premier temps à la position d’observation et ensuite, essaye de faire un pick par vision dans le workspace
robot.arm.move_pose(observation_pose)
obj_found, shape, color = robot.vision.vision_pick(workspace_name)
Si le pick par vision échoue, on attend 0.1 seconde, on lance ensuite une nouvelle itération
if not obj_found:
robot.wait(0.1)
continue
Sinon, on calcule la nouvelle position selon le nombre de saisies, ensuite, on dépose l’objet à cette position
next_place_pose = place_pose.copy_with_offsets(x_offset=catch_count * offset_size)
robot.pick_place.place_from_pose(next_place_pose)
On incrémente également la variable catch_count
catch_count += 1
Une fois que le nombre de cible attrapé est atteint, on se met en veille
robot.arm.go_to_sleep()
Conditionnement Multi-référence
Lors d’une tâche de conditionnement, les objets ne seront pas forcément placés au même endroit en fonction de leur type. Dans cet exemple, nous verrons comment aligner des objets en fonction de leur couleur, en utilisant l’élémnet couleur ObjectColor
retourné par la fonction vision_pick()
# Distance between elements
offset_size = 0.05
max_failure_count = 3
# Dict to write catch history
count_dict = {
ObjectColor.BLUE: 0,
ObjectColor.RED: 0,
ObjectColor.GREEN: 0,
}
try_without_success = 0
# Loop until too much failures
while try_without_success < max_failure_count:
# Moving to observation pose
robot.arm.move_pose(observation_pose)
# Trying to get object via Vision Pick
obj_found, shape, color = robot.vision.vision_pick(workspace_name)
if not obj_found:
try_without_success += 1
robot.wait(0.1)
continue
# Choose X position according to how the color line is filled
offset_x_ind = count_dict[color]
# Choose Y position according to ObjectColor
if color == ObjectColor.BLUE:
offset_y_ind = -1
elif color == ObjectColor.RED:
offset_y_ind = 0
else:
offset_y_ind = 1
# Going to place the object
next_place_pose = place_pose.copy_with_offsets(x_offset=offset_x_ind * offset_size,
y_offset=offset_y_ind * offset_size)
robot.pick_place.place_from_pose(next_place_pose)
# Increment count
count_dict[color] += 1
try_without_success = 0
robot.arm.go_to_sleep()
Détails de code - Conditionnement Multi-Reference
On souhaite attraper des objets jusqu’à ce que le pick par vision échoue max_failure_count
fois. Chaque objet sera placé dans une colonne spécifique en fonction de sa couleur. Le nombre de saisies pour chaque couleur est enregistré dans un dictionnaire count_dict
# Distance between elements
offset_size = 0.05
max_failure_count = 3
# Dict to write catch history
count_dict = {
ObjectColor.BLUE: 0,
ObjectColor.RED: 0,
ObjectColor.GREEN: 0,
}
try_without_success = 0
# Loop until too much failures
while try_without_success < max_failure_count:
Pour chaque itération, on se rend dans un premier temps à la position d’observation et ensuite, essaye de faire un pick par vision dans le workspace
robot.move_pose(observation_pose)
obj_found, shape, color = robot.vision.vision_pick(workspace_name)
Si la saisie par vision échoue, on attend 0.1 seconde, on commence ensuite une nouvelle iteration, sans oublier d’augmenter le compteur d’échec
if not obj_found:
try_without_success += 1
robot.wait(0.1)
continue
Sinon, on calcule la nouvelle position selon le nombre de saisies, ensuite, on dépose l’objet à cette position
# Choose X position according to how the color line is filled
offset_x_ind = count_dict[color]
# Choose Y position according to ObjectColor
if color == ObjectColor.BLUE:
offset_y_ind = -1
elif color == ObjectColor.RED:
offset_y_ind = 0
else:
offset_y_ind = 1
# Going to place the object
next_place_pose = place_pose.copy_with_offsets(x_offset=offset_x_ind * offset_size,
y_offset=offset_y_ind * offset_size)
robot.pick_place.place_from_pose(next_place_pose)
On incrémente le dictionnaire count_dict
et on réinitialise try_without_success
count_dict[color] += 1
try_without_success = 0
Une fois que le nombre de cible attrapé est atteint, on se met en veille
robot.arm.go_to_sleep()
Tri avec un convoyeur
Une manière intéressante d’amener des objets au robot, est d’utiliser le convoyeur. Dans ces exemples, on verra comment attraper seulement un certain type d’objet en stoppant le convoyeur dès que l’objet est détecté dans le workspace
# Initializing variables
offset_size = 0.05
max_catch_count = 4
shape_expected = ObjectShape.CIRCLE
color_expected = ObjectColor.RED
conveyor_id = robot.conveyor.set_conveyor()
catch_count = 0
while catch_count < max_catch_count:
# Turning conveyor on
robot.conveyor.run_conveyor(conveyor_id)
# Moving to observation pose
robot.arm.move_pose(observation_pose)
# Check if object is in the workspace
obj_found, pos_array, shape, color = robot.vision.detect_object(workspace_name,
shape=shape_expected,
color=color_expected)
if not obj_found:
robot.wait(0.5) # Wait to let the conveyor turn a bit
continue
# Stopping conveyor
robot.conveyor.stop_conveyor(conveyor_id)
# Making a vision pick
obj_found, shape, color = robot.visionvision_pick(workspace_name,
shape=shape_expected,
color=color_expected)
if not obj_found: # If visual pick did not work
continue
# Calculate place pose and going to place the object
next_place_pose = place_pose.copy_with_offsets(x_offset=catch_count * offset_size)
robot.pick_place.place_from_pose(next_place_pose)
catch_count += 1
# Stopping & unsetting conveyor
robot.conveyor.stop_conveyor(conveyor_id)
robot.conveyor.unset_conveyor(conveyor_id)
robot.arm.go_to_sleep()
Détails de code - Tri
Dans un premier temps, on initialise le processus : on veut que le robot attrape 4 cerlces rouges. Pour cela, on règle les variables shape_expected
et color_expected
avec ObjectShape.CIRCLE
et ObjectColor.RED
offset_size = 0.05
max_catch_count = 4
shape_expected = ObjectShape.CIRCLE
color_expected = ObjectColor.RED
On active la connexion avec le convoyeur et on démarre une boucle jusqu’à ce que le robot ait attrapé max_catch_count
objets
conveyor_id = robot.set_conveyor()
catch_count = 0
while catch_count < max_catch_count:
Pour chaque itération, on démarre d’abord le convoyeur (s’il est déjà en train de tourner, cela ne fait rien), on se déplace ensuite à la position d’observation
# Turning conveyor on
robot.conveyor.run_conveyor(conveyor_id)
# Moving to observation pose
robot.arm.move_pose(observation_pose)
On vérifie ensuite si un objet correspond à notre critère est dans le workspace. Sinon, on attend 0.5 seconde, on démarre ensuite une nouvelle itération
obj_found, pos_array, shape, color = robot.vision.detect_object(workspace_name,
shape=shape_expected,
color=color_expected)
if not obj_found:
robot.wait(0.5) # Wait to let the conveyor turn a bit
continue
Sinon, on stoppe le convoyeur et on essaye de faire une saisie par vision
# Stopping conveyor
robot.conveyor.stop_conveyor(conveyor_id)
# Making a vision pick
obj_found, shape, color = robot.vision.vision_pick(workspace_name,
shape=shape_expected,
color=color_expected)
if not obj_found: # If visual pick did not work
continue
Si la saisie par vision réussie, on calcule une nouvelle position de dépôt, et on y place l’objet
# Calculate place pose and going to place the object
next_place_pose = place_pose.copy_with_offsets(x_offset=catch_count * offset_size)
robot.pick_place.place_from_pose(next_place_pose)
catch_count += 1
Une fois que le nombre de cible attrapée est atteint, on arrête le convoyeur et on se met en veille
# Stopping & unsetting conveyor
robot.conveyor.stop_conveyor(conveyor_id)
robot.conveyor.unset_conveyor(conveyor_id)
robot.arm.go_to_sleep()