EVA "Armbot" and "Kinematics" Control Classes
Files available at EVA Armbot Class || Google Drive. Simplified user control class. "Armbot" control class developed in Python for two Automata "Eva" robot arms, using Automata EVA API calls, solving forward and inverse kinematics for the end efector position by applying lagrangian-jacobian matrix computation. Using Python.
Overview
This project provides a Python-based control class for managing two Automata "Eva" robot arms. The control class leverages Automata's EVA API to interact with the robots, solving forward and inverse kinematics problems. The solutions are based on the Lagrangian-Jacobian matrix computation method. This method is essential for calculating the positions of the robot arms' end effectors—i.e., the parts of the arms that interact with the environment. By using the provided scripts, users can effectively control the robot arms for various applications.
Project Files
Here is a brief overview of the critical files and their purposes:
SDKs:
evasdk/
: The SDK to use the EVA control class. Uses API calls to interface with the robot arms via ethernet.aravis.py
: The SDK to use the network cameras. This must be placed in the same directory as thearmbot
class being utilized.
Control Classes
armbot.py
: Contains the main class for robot arm control.kinematics.py
: Implements the kinematics algorithms using Lagrangian-Jacobian matrix computations.
Tests and Samples
samples/
: Directory containing examples and tests for both the kinematics and thearmbot
control class.armbot/
: Several test files (armbot class test 1.py
toarmbot class test 5.py
). These scripts demonstrate various use cases of theArmbot
class.kinematics/
: *sample code 1.py
tosample code 4.py
. Additional examples showing different functionalities of the robot armskinematics
class.
Scripts
reset_position.py
: A utility script to reset the robot arms to their initial positions.pick_and_place.py
: Sample script that uses thearmbot
class to perform a simple, pre-programmed pick and place operation.hello_arm.py
: Sample script that uses thearmbot
class to say "hello".
Getting Started
Prerequisites:
To run this project, you need Python installed on your system (Python 3.6 or newer is recommended). Additionally, you must install the following libraries:
Python:
version 3.6.0++
NumPy:
For numerical calculations
Matplotlib:
For plotting and visualization of the robot's movements
SymPy:
For symbolic mathematics and kinematics calculations
OpenCV (cv2):
For image processing and computer vision tasks
Threading:
For parallel execution of image acquisition and processing
evasdk (specific to the EVA robotic arm, included in evasdk folder):
For eva robot arm control
aravis:
For camera control
You can install these packages using pip:
$ pip install numpy matplotlib sympy opencv-python aravis
Installation
Download all files in
Install all dependencies, specified above in ”prerequisites”.
Usage
To test the Armbot class with one of the test scripts, follow these steps:
Ensure your environment is set up with all necessary dependencies. Navigate to the project directory.
To run a test script
Navigate to the sample directory where the file is located. Make sure the kinematics
, armbot
, aravis
and evasdk
packages are located in the same directory. Then run:
$ python3 <script name>.py
To run the pick and place script
This script executes a simple pick and place operation. You must first place the object to be picked, typically a cube, just in front of the robot arm, in the marked target position. Afterwards, in the main project directory, run the following:
$ python3 pick_and_place.py
To run the hello arm script
This script makes the robot arm wave its arm as if it is saying "hello". To run it, simply execute the following in the main project directory:
$ python3 hello_arm.py
To run the reset position script
In order to reset the arms pose to its original position, facing up, this script can be executed by running the following in the main project directory:
$ python3 reset_position.py
Key Components
Kinematics: Mathematical Foundations
kinematics.py
defines the Kinematics class responsible for calculating the robot arm's movements. It uses mathematical models to determine how the arm should move its joints to reach a specific position.
Inverse Kinematics and the Jacobian Matrix
Inverse kinematics is the process of determining the joint parameters that provide a desired position of the robot's end effector. The Jacobian matrix is a critical tool in solving inverse kinematics problems because it relates the change in joint angles to the resulting movement of the end effector in space.
In the Kinematics class, we calculate the Jacobian matrix as follows:
# Calculate the numerical value of J (jacobian) at each point, # you can produce the Jacobian as follows J = p.jacobian(theta) J_i = J.subs({theta1:theta_i[0], theta2:theta_i[1], theta3:theta_i[2], theta4:theta_i[3], theta5:theta_i[4], theta6:theta_i[5]}).evalf()
Where p
is the position vector of the end effector, and theta
represents the joint angles.
To move the end effector towards a target, we adjust the joint angles based on the calculated differential movement dp
. The Jacobian inverse is used to find the necessary change in joint angles dtheta
to achieve dp
:
J_inv = J_i.pinv() dtheta = J_inv * dp_step
dp_step
is the desired small step towards the target position. The pseudoinverse (pinv()
) of the Jacobian is used when the matrix is not square, ensuring a solution exists.
ArmBot
The ArmBot class, defined in armbot.py
, using the kinematics class to control the robotic arm and integrates computer vision for object detection. To start the class you must first create an instance of it by providing the arm name as follows:
arm = Arm("evatrendylimashifterpt410")
Or the arm IP:
arm = Arm("144.32.152.105")
The arm and camera names and ips can be changed in the "initialize_arm()" and the "initialize_camera()" functions within the armbot class. To see the available IPs and hostnames for both arms and for the cameras, see the following article: https://uoy.atlassian.net/wiki/x/YobcAg .
After an arm object has been instantiated, functions can be run using dot notation as usual. Key functions include:
Main Functions of ArmBot Class
move_end_efector(absolute_position): Moves the end effector to an absolute position.
shift_end_efector(relative_position): Adjusts the end effector's position relative to its current location.
set_joint_angles(joint_angles): Moves arm by directly commanding each joint to move to the specified angle in radians (6DOF).
open_gripper() and close_gripper(): Controls the gripper to pick up or release objects.
start_image_acquisition(): Starts continuous image acquisition and processing, in parallel thread.
get_current_image(): Returns current image in continuous feed thread.
take_picture(): Takes and returns single picture without having to start a parallel continuous feed.
detect_colour(image, colour_name): Identifies objects in the image based on their color.
detect_shapes(mask, shape_name): Detects geometric shapes within a masked image.
Sample Scripts
Pick and Place
This script, pick_and_place.py
, is designed to control two robotic arms for a pick-and-place operation. Utilizing the ArmBot
class, the script coordinates the movements of both arms to pick up objects from one location and place them in another. This example provides a clear demonstration of how to use the ArmBot class to manage multiple robotic arms simultaneously in a Python script.
Main Functionality
The main
function performs several steps:
Initialize Two ArmBots: Each
ArmBot
instance is created with a uniquehostname
, which corresponds to specific network details for each robotic arm. You can find more about network configurations on the internal network documentation or at the provided link in the script comments and in the following article: https://uoy.atlassian.net/wiki/x/YobcAg.
# Details to connect to the robot arm, more info here:
# https://wiki.york.ac.uk/display/TSS/Network+Details+and+Credentials+for+the+EVA+Arms+and+Network+Cameras
arm1 = ArmBot("evatrendylimashifterpt410");
arm2 = ArmBot("evacunningyorkartistpt410");
Operational Sequence:
Each robotic arm is homed using
home_robot()
, which positions the arm at a starting configuration.The gripper on each arm is opened with
open_gripper()
, preparing to pick up an object.Each arm moves to a specified location (
move_end_efector([0, -0.2, 0.18])
), closes its gripper (close_gripper()
), and then returns to the home position.The arms then move to place the objects at new locations, open the grippers to release the objects, and finally return to the home position where the grippers are closed.
Error Handling:
The operations are enclosed in a
try-except
block to handle interruptions like aKeyboardInterrupt
. This is essential for stopping the script safely without leaving the robotic arms in an unstable state.The
finally
block can include commands to reset the arms or ensure all resources are properly released, though these commands are commented out by default to emphasize the need for manual inspection post-error.
Example Code
Here is a sample snippet from the script showing how one robotic arm is controlled:
try:
# Home robot and open the gripper
arm1.home_robot();
arm1.open_gripper();
# Move to the target position and close the gripper
arm1.move_end_efector([0, -0.2, 0.18]);
arm1.close_gripper();
arm1.home_robot();
# Move to the drop-off location and open thye gripper to release the object
arm1.move_end_efector([0.2, -0.2, 0.22]);
arm1.open_gripper();
# Home robot and close the gripper
arm1.home_robot();
arm1.close_gripper();
except KeyboardInterrupt:
print("Exiting...")
Hello Arm
This script, titled hello_arm.py
, is designed to demonstrate basic operations of a robotic arm using the ArmBot
class. With this script the arm says "hello" by waving back and forth between two positions. It involves moving the robotic arm through a sequence of positions while opening and closing the gripper, showcasing the arm's capabilities in a simple and repetitive manner.
Main Functionality
The main
function orchestrates a series of movements and gripper operations to demonstrate the robotic arm's functionality:
Initialization:
An instance of ArmBot is created for the robot arm, initialized with its specific network hostname.
A connection to the robotic arm is established based on this hostname.
Operational Sequence:
The robotic arm is commanded to return to its 'home' position to start from a known state.
The arm then performs a series of movements to two different positions, alternating between opening and closing the gripper at each position.
After performing these operations, the arm returns to the initial positions to repeat the gripper actions.
Finally, the arm returns to the 'home' position, ensuring it ends in a safe, default state.
Error Handling:
The script includes a
try-except
block to gracefully handle interruptions (likeKeyboardInterrupt
), allowing for safe termination of the program.The
finally
block is prepared for resetting the arm if needed, though the reset command is commented out to emphasize manual inspection before automated restarts.
Example Code
Here's a snippet showing the movement and gripper control sequence:
try:
arm.home_robot();
pose1 = arm.move_end_efector([0.2, -0.2, 0.5]);
arm.open_gripper();
time.sleep(0.2)
arm.close_gripper();
time.sleep(0.2)
pose2 = arm.move_end_efector([-0.2, -0.2, 0.5]);
arm.open_gripper();
time.sleep(0.2)
arm.close_gripper();
time.sleep(0.2)
arm.set_joint_angles(pose1)
arm.open_gripper();
time.sleep(0.2)
arm.close_gripper();
time.sleep(0.2)
arm.set_joint_angles(pose2)
arm.open_gripper();
time.sleep(0.2)
arm.close_gripper();
time.sleep(0.2)
arm.home_robot();
except KeyboardInterrupt:
print("Exiting...")
Reset Position
This script, reset_position.py
, is designed to reset two robotic arms to their default joint angles (facing up, so that the projector screen can be opened) using the ArmBot
class. It serves as a basic utility script to ensure that the robotic arms are in a known, neutral state before starting any operations or after completing tasks to ensure safety and readiness for future operations.
Main Functionality
The main
function manages the resetting of joint angles for two robotic arms:
Initialization:
Two instances of
ArmBot
are created for each robot arm, initialized with their respective network hostnames.A connection to each robotic arm is established based on these hostnames.
arm1 = ArmBot("evatrendylimashifterpt410");
arm2 = ArmBot("evacunningyorkartistpt410");
Operational Sequence:
Both robotic arms are instructed to set their joint angles to [0,0,0,0,0,0], which represents the default or neutral position for the arms.
This position ensures that the arms are aligned straight without any bends or twists, which is often used as a safe configuration for starting or ending robotic operations.
Error Handling:
A try-except block captures KeyboardInterrupt to allow for safe termination of the program during manual interruptions.
The finally block is set up to potentially reset the arms if needed, though the reset command is commented out to stress the importance of manual inspection before automated resets.
Example Code
Here's a simple code snippet illustrating how both robotic arms are reset to default positions:
try:
arm1.set_joint_angles([0,0,0,0,0,0]);
arm2.set_joint_angles([0,0,0,0,0,0]);
except KeyboardInterrupt:
print("Exiting...")