Examples: Vision

This page shows how to use Ned’s Vision Set.

If you want to see more about Ned’s Vision functions, you can look at PyNiryo - Vision
If you want to see how to do Image Processing, go check out the Image Processing section.

Note

Even if you do not own a Vision Set, you can still realize these examples with the Gazebo simulation version.

Danger

If you are using the real robot, make sure the environment around it is clear.

Needed piece of code

Important

In order to achieve the following examples, you need to create a vision workspace. In this page, the workspace used is named workspace_1. To create it, the user should go on Niryo Studio!

As the examples start always the same, add the following lines at the beginning of codes

vision_header.py
 1# Imports
 2from pyniryo import NiryoRobot, PoseObject
 3
 4# - Constants
 5workspace_name = "workspace_1"  # Robot's Workspace Name
 6robot_ip_address = '<robot_ip_address>'
 7
 8# The pose from where the image processing happens
 9observation_pose = PoseObject(0.16, 0.0, 0.35, 3.14, 0.0, 0.0)
10# Place pose
11place_pose = PoseObject(0.01, -0.2, 0.12, 3.14, -0.01, -1.5)
12
13# - Initialization
14
15# Connect to robot
16robot = NiryoRobot(robot_ip_address)
17# Calibrate robot if the robot needs calibration
18robot.calibrate_auto()
19# Updating tool
20robot.update_tool()

Hint

All the following examples are only a part of what can be made with the API in terms of Vision. We advise you to look at API - Vision to understand more deeply

Simple Vision Pick & Place

The goal of a Vision Pick & Place is the same as a classical Pick & Place, with a close difference: the camera detects where the robot has to go in order to pick!

This short example shows how to do your first Vision pick using the vision_pick() function:

1from vision_header import robot, observation_pose, workspace_name, place_pose
2
3robot.move(observation_pose)
4# Trying to pick target using camera
5obj_found, shape_ret, color_ret = robot.vision_pick(workspace_name)
6if obj_found:
7    robot.place_from_pose(place_pose)
8
9robot.set_learning_mode(True)

Code Details - Simple Vision Pick and Place

To execute a Vision pick, we firstly need to go to a place where the robot will be able to see the workspace

3robot.move(observation_pose)

Then, we try to perform a Vision pick in the workspace with the vision_pick() function:

5obj_found, shape_ret, color_ret = robot.vision_pick(workspace_name)

Variables shape_ret and color_ret are respectively of type ObjectShape and ObjectColor, and store the shape and the color of the detected object! We will not use them for this first example.

The obj_found variable is a boolean which indicates whereas an object has been found and picked, or not. Thus, if the pick worked, we can place the object at the place pose.

6if obj_found:
7    robot.place_from_pose(place_pose)

Finally, we turn learning mode on

9robot.set_learning_mode(True)

Note

If your obj_found variable indicates False, check that:

  • Nothing obstructs the camera field of view

  • Workspace’s 4 markers are visible

  • At least 1 object is placed fully inside the workspace

First conditioning via Vision

In most of use cases, the robot will need to perform more than one Pick & Place. In this example, we will see how to condition multiple objects according to a straight line:

 1from vision_header import robot, observation_pose, workspace_name, place_pose
 2
 3# Initializing variables
 4offset_size = 0.05
 5max_catch_count = 4
 6
 7# Loop until enough objects have been caught
 8catch_count = 0
 9while catch_count < max_catch_count:
10    # Moving to observation pose
11    robot.move(observation_pose)
12
13    # Trying to get object via Vision Pick
14    obj_found, shape, color = robot.vision_pick(workspace_name)
15    if not obj_found:
16        robot.wait(0.1)
17        continue
18
19    # Calculate place pose and going to place the object
20    next_place_pose = place_pose.copy_with_offsets(x_offset=catch_count * offset_size)
21    robot.place_from_pose(next_place_pose)
22
23    catch_count += 1
24
25robot.go_to_sleep()

Code Details - First Conditioning via Vision

We want to catch max_catch_count objects, and space each of them by offset_size meter:

4offset_size = 0.05
5max_catch_count = 4

We start a loop until the robot has caught max_catch_count objects:

8catch_count = 0
9while catch_count < max_catch_count:

For each iteration, we firstly go to the observation pose and then, try to make a Vision pick in the workspace:

11    robot.move(observation_pose)
12
13    # Trying to get object via Vision Pick
14    obj_found, shape, color = robot.vision_pick(workspace_name)

If the Vision pick failed, we wait 0.1 second and then, start a new iteration:

15    if not obj_found:
16        robot.wait(0.1)
17        continue

Else, we compute the new place position according to the number of catches, and then, go placing the object at that place:

20    next_place_pose = place_pose.copy_with_offsets(x_offset=catch_count * offset_size)
21    robot.place_from_pose(next_place_pose)

We also increment the catch_count variable

23    catch_count += 1

Once the target catch number is achieved, we go to sleep:

25robot.go_to_sleep()

Multi Reference Conditioning

During a conditioning task, objects may not always be placed as the same place according to their type. In this example, we will see how to align object according to their color, using the color element ObjectColor returned by vision_pick() function

 1from vision_header import robot, observation_pose, workspace_name, place_pose
 2from pyniryo import ObjectColor
 3
 4# Distance between elements
 5offset_size = 0.05
 6max_failure_count = 3
 7
 8# Dict to write catch history
 9count_dict = {
10    ObjectColor.BLUE: 0,
11    ObjectColor.RED: 0,
12    ObjectColor.GREEN: 0,
13}
14
15try_without_success = 0
16# Loop until too much failures
17while try_without_success < max_failure_count:
18    # Moving to observation pose
19    robot.move(observation_pose)
20    # Trying to get object via Vision Pick
21    obj_found, shape, color = robot.vision_pick(workspace_name)
22    if not obj_found:
23        try_without_success += 1
24        robot.wait(0.1)
25        continue
26
27    # Choose X position according to how the color line is filled
28    offset_x_ind = count_dict[color]
29
30    # Choose Y position according to ObjectColor
31    if color == ObjectColor.BLUE:
32        offset_y_ind = -1
33    elif color == ObjectColor.RED:
34        offset_y_ind = 0
35    else:
36        offset_y_ind = 1
37
38    # Going to place the object
39    next_place_pose = place_pose.copy_with_offsets(x_offset=offset_x_ind * offset_size,
40                                                   y_offset=offset_y_ind * offset_size)
41    robot.place_from_pose(next_place_pose)
42
43    # Increment count
44    count_dict[color] += 1
45    try_without_success = 0
46
47robot.go_to_sleep()

Code Details - Multi Reference Conditioning

We want to catch objects until Vision Pick failed max_failure_count times. Each of the object will be put on a specific column according to its color. The number of catches for each color will be stored on a dictionary count_dict.

 4# Distance between elements
 5offset_size = 0.05
 6max_failure_count = 3
 7
 8# Dict to write catch history
 9count_dict = {
10    ObjectColor.BLUE: 0,
11    ObjectColor.RED: 0,
12    ObjectColor.GREEN: 0,
13}
14
15try_without_success = 0
16# Loop until too much failures
17while try_without_success < max_failure_count:

For each iteration, we firstly go to the observation pose and then, try to make a Vision pick in the workspace

19    robot.move(observation_pose)
20    # Trying to get object via Vision Pick
21    obj_found, shape, color = robot.vision_pick(workspace_name)

If the Vision pick failed, we wait 0.1 second and then, start a new iteration, without forgetting to increment the failure counter

22    if not obj_found:
23        try_without_success += 1
24        robot.wait(0.1)
25        continue

Else, we compute the new place position according to the number of catches, and then, go place the object at that place:

27    # Choose X position according to how the color line is filled
28    offset_x_ind = count_dict[color]
29
30    # Choose Y position according to ObjectColor
31    if color == ObjectColor.BLUE:
32        offset_y_ind = -1
33    elif color == ObjectColor.RED:
34        offset_y_ind = 0
35    else:
36        offset_y_ind = 1
37
38    # Going to place the object
39    next_place_pose = place_pose.copy_with_offsets(x_offset=offset_x_ind * offset_size,
40                                                   y_offset=offset_y_ind * offset_size)
41    robot.place_from_pose(next_place_pose)

We increment the count_dict dictionary and reset try_without_success:

44    count_dict[color] += 1
45    try_without_success = 0

Once the target catch number is achieved, we go to sleep:

47robot.go_to_sleep()

Sorting Pick with Conveyor

An interesting way to bring objects to the robot, is the use of a Conveyor Belt. In this examples, we will see how to catch only a certain type of object by stopping the conveyor as soon as the object is detected on the workspace.

 1from vision_header import robot, workspace_name, observation_pose, place_pose
 2from pyniryo import ObjectColor, ObjectShape
 3
 4# Initializing variables
 5offset_size = 0.05
 6max_catch_count = 4
 7shape_expected = ObjectShape.CIRCLE
 8color_expected = ObjectColor.RED
 9
10conveyor_id = robot.set_conveyor()
11
12catch_count = 0
13while catch_count < max_catch_count:
14    # Turning conveyor on
15    robot.run_conveyor(conveyor_id)
16    # Moving to observation pose
17    robot.move(observation_pose)
18    # Check if object is in the workspace
19    obj_found, pos_array, shape, color = robot.detect_object(workspace_name, shape=shape_expected, color=color_expected)
20    if not obj_found:
21        robot.wait(0.5)  # Wait to let the conveyor turn a bit
22        continue
23    # Stopping conveyor
24    robot.stop_conveyor(conveyor_id)
25    # Making a vision pick
26    obj_found, shape, color = robot.vision_pick(workspace_name, shape=shape_expected, color=color_expected)
27    if not obj_found:  # If visual pick did not work
28        continue
29
30    # Calculate place pose and going to place the object
31    next_place_pose = place_pose.copy_with_offsets(x_offset=catch_count * offset_size)
32    robot.place(next_place_pose)
33
34    catch_count += 1
35
36# Stopping & unsetting conveyor
37robot.stop_conveyor(conveyor_id)
38robot.unset_conveyor(conveyor_id)
39
40robot.go_to_sleep()

Code Details - Sort Picking

Firstly, we initialize your process: we want the robot to catch 4 red circles. To do so, we set variables shape_expected and color_expected with ObjectShape.CIRCLE and ObjectColor.RED.

5offset_size = 0.05
6max_catch_count = 4
7shape_expected = ObjectShape.CIRCLE
8color_expected = ObjectColor.RED

We activate the connection with the Conveyor Belt and start a loop until the robot has caught max_catch_count objects

10conveyor_id = robot.set_conveyor()
11
12catch_count = 0
13while catch_count < max_catch_count:

For each iteration, we firstly run the Conveyor Belt (if the latter is already running, nothing will happen), then go to the observation pose

14    # Turning conveyor on
15    robot.run_conveyor(conveyor_id)
16    # Moving to observation pose
17    robot.move(observation_pose)

We then check if an object corresponding to our criteria is in the workspace. If not, we wait 0.5 second and then, start a new iteration

19    obj_found, pos_array, shape, color = robot.detect_object(workspace_name, shape=shape_expected, color=color_expected)
20    if not obj_found:
21        robot.wait(0.5)  # Wait to let the conveyor turn a bit
22        continue

Else, stop the Conveyor Belt and try to make a Vision pick

23    # Stopping conveyor
24    robot.stop_conveyor(conveyor_id)
25    # Making a vision pick
26    obj_found, shape, color = robot.vision_pick(workspace_name, shape=shape_expected, color=color_expected)
27    if not obj_found:  # If visual pick did not work
28        continue

If Vision Pick succeed, compute new place pose, and place the object

30    # Calculate place pose and going to place the object
31    next_place_pose = place_pose.copy_with_offsets(x_offset=catch_count * offset_size)
32    robot.place(next_place_pose)
33
34    catch_count += 1

Once the target catch number is achieved, we stop the Conveyor Belt and go to sleep

36# Stopping & unsetting conveyor
37robot.stop_conveyor(conveyor_id)
38robot.unset_conveyor(conveyor_id)
39
40robot.go_to_sleep()