Exemples: Vision

Cette page explique comment utiliser le set vision du Ned

Si vous voulez en savoir plus sur les fonctions de vision du Ned, vous pouvez regarder PyNiryo - Vision
Si vous voulez voir comment faire du traitement d’image, regardez la première version de la documentation PyNiryo2

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()