Skip to content

Commit

Permalink
All pre-commit checks passing
Browse files Browse the repository at this point in the history
  • Loading branch information
LuckierDodge committed Feb 9, 2024
1 parent b15b344 commit 9afac5a
Show file tree
Hide file tree
Showing 17 changed files with 229 additions and 1,404 deletions.
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,4 @@ enforcement ladder](https://github.com/mozilla/diversity).

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
https://www.contributor-covenant.org/translations.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Sciclops has 4 controllable axes and a gripper.

### Python

You'll need `libusb` installed (on debian-based linux: `sudo apt install libusb-1.0-0-dev`)

```bash
# Create a virtual environment named .venv
python -m venv .venv
Expand Down
1 change: 1 addition & 0 deletions platecrane_driver/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
"""Driver for Hudson Robotics PlateCranes."""
__version__ = "0.1.0"
23 changes: 22 additions & 1 deletion platecrane_driver/error_codes.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Defines exceptions for error codes returned by the plate crane controller."""
from __future__ import annotations


Expand All @@ -9,6 +10,7 @@ class SerialError(Exception):

@staticmethod
def from_response(response: str) -> SerialError:
"""Create a SerialError from a response string."""
error_map = {
"E0": RelayError,
"E1": CommandError,
Expand All @@ -23,39 +25,57 @@ def from_response(response: str) -> SerialError:


class RelayError(SerialError):
"""Undefined timer, counter, data memory. Check if requested unit is valid. Corresponds to the response E0."""

def __init__(self):
"""Create a new RelayError."""
super().__init__(
"Undefined timer, counter, data memory. Check if requested unit is valid."
)


class CommandError(SerialError):
"""Invalid Command. Corresponds to the response E1."""

def __init__(self):
"""Create a new CommandError."""
super().__init__(
"Invalid command. Check if communication is opened by CR, check command sent to controller, "
"check for interruptions during string transmission."
)


class ProgramError(SerialError):
"""Firmware issues. Corresponds to the response E2."""

def __init__(self):
"""Create a new ProgramError."""
super().__init__("Firmware lost, reprogram controller")


class HardwareError(SerialError):
"""Hardware faults. Corresponds to the response E3."""

def __init__(self):
"""Create a new HardwareError."""
super().__init__(
"Controller hardware error, turn controller ON/OFF, controller is faulty and has to be replaced."
)


class WriteProtectedError(SerialError):
"""Write protected error. Corresponds to the response E4."""

def __init__(self):
"""Create a new WriteProtectedError."""
super().__init__("Unauthorized access")


class BaseUnitError(SerialError):
"""Base unit error. Corresponds to the response E5."""

def __init__(self):
"""Create a new BaseUnitError."""
super().__init__("Unauthorized access")


Expand All @@ -64,6 +84,7 @@ class ErrorResponse(Exception):

@staticmethod
def from_error_code(error_code: int) -> ErrorResponse:
"""Create an ErrorResponse from an integer error code."""
error_code = int(
hex(error_code)[-2:], base=16
) # convert to hex, take two last digits, parse as hex
Expand All @@ -79,7 +100,7 @@ def from_error_code(error_code: int) -> ErrorResponse:
0x0B: "Lift overflow; travel path exceeds maximum allowed path",
0x0C: "Wrong Level; DM5 > DM25; Level does exceed the maximum available levels",
0x0D: "Plate trace Error; Plate was not loaded/unloaded as expected from/to shovel",
0x0E: "Init time out; System was not able to initilize",
0x0E: "Init time out; System was not able to initialize",
0x10: "Turn in Turn Init Sensor or not in safe position; Possible step loss",
0x12: "Carousel Init time out",
0x13: "Shovel OUT time out; shovel could not be extended",
Expand Down
11 changes: 0 additions & 11 deletions platecrane_driver/plate_handler.py

This file was deleted.

10 changes: 5 additions & 5 deletions platecrane_driver/plate_resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},

"96_deep_well":{
"plate_above_height":5000,
"plate_above_height":5000,
"plate_pick_steps_module": 2950,
"plate_pick_steps_stack": 7750,
"plate_lid_steps": 0,
Expand All @@ -25,20 +25,20 @@
},

"tip_box_lid_on":{
"plate_above_height":5000,
"plate_above_height":5000,
"plate_pick_steps_module": 2300,
"plate_pick_steps_stack": 7100,
"plate_lid_steps": 6200,
"lid_height": 400

},
"tip_box_lid_off":{
"plate_above_height":5000,
"plate_above_height":5000,
"plate_pick_steps_module": 3100,
"plate_pick_steps_stack": 7900,
"plate_lid_steps": 0,
"lid_height": 0

}
}

}
8 changes: 3 additions & 5 deletions platecrane_driver/platecrane_driver.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Handle Proper Interfacing with the PlateCrane"""
import json
import re

Expand Down Expand Up @@ -90,11 +91,6 @@ def home(self, timeout=28):
command = "HOME\r\n"
self.__serial_port.send_command(command, timeout)

def get_error_output(self, output: str):
# Find the errors from error codes.
self.robot_error = "err"
pass

def get_robot_movement_state(self):
"""Summary
Expand Down Expand Up @@ -150,10 +146,12 @@ def get_status(self):
self.robot_status = self.__serial_port.send_command(command)

def free_joints(self):
"""Unlocks the joints of the plate_crane"""
command = "limp TRUE\r\n"
self.__serial_port.send_command(command)

def lock_joints(self):
"""Locks the joints of the plate_crane"""
command = "limp FALSE\r\n"
self.__serial_port.send_command(command)

Expand Down
1 change: 1 addition & 0 deletions platecrane_driver/platecrane_joint_limits.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Joint limits for the platecrane."""
platecrane_joint_limits = {
"R": [-1200, 10200],
"Z": [-13600, 300],
Expand Down
33 changes: 0 additions & 33 deletions platecrane_driver/platecrane_locations.py

This file was deleted.

28 changes: 12 additions & 16 deletions platecrane_driver/sciclops_driver.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Driver for the Hudson Robotics Sciclops robot."""
import asyncio
import re

Expand All @@ -12,6 +13,7 @@ class SCICLOPS:
"""

def __init__(self, VENDOR_ID=0x7513, PRODUCT_ID=0x0002):
"""Creates a new SCICLOPS driver object. The default VENDOR_ID and PRODUCT_ID are for the Sciclops robot."""
self.VENDOR_ID = VENDOR_ID
self.PRODUCT_ID = PRODUCT_ID
self.host_path = self.connect_sciclops()
Expand Down Expand Up @@ -39,7 +41,7 @@ def __init__(self, VENDOR_ID=0x7513, PRODUCT_ID=0x0002):

def connect_sciclops(self):
"""
Connect to serial port / If wrong port entered inform user
Connect to USB device. If wrong device, inform user
"""
host_path = usb.core.find(idVendor=self.VENDOR_ID, idProduct=self.PRODUCT_ID)

Expand All @@ -51,6 +53,7 @@ def connect_sciclops(self):
return host_path

def disconnect_robot(self):
"""Disconnects from the sciclops robot."""
try:
usb.util.dispose_resources(self.host_path)
except Exception as err:
Expand Down Expand Up @@ -775,19 +778,10 @@ def limp(self, limp_bool):
command = "LIMP %s" % limp_string # Command interpreted by Sciclops
self.send_command(command)

# TODO: see if way to update exchange labware info after p400 puts plate there (probably needs to be in seperate file)
"""
functions to add
"""

# TODO: function probably only needed if labware stored on separate file
def update_labware(plate_type, source, destination):
pass

# * checks all lid nests to see if there's a lid of same type present, returns occupied lid nest
def check_for_lid(
self,
): # TODO: conditional for no available lid to prevent delays?
"""Checks all lid nests to see if there's a lid of same type present, returns occupied lid nest"""
if (
self.labware["lidnest1"]["howmany"] >= 1
and self.labware["lidnest1"]["type"] == self.labware["exchange"]["type"]
Expand All @@ -806,6 +800,7 @@ def check_for_lid(
def check_for_empty_nest(
self,
): # TODO: maybe add conditional to throw away lids in nests if none available?
"""Check all lid nests to see if there's an empty "available" lid nest, returns open lid nest"""
if self.labware["lidnest1"]["howmany"] == 0:
return "lidnest1"
elif self.labware["lidnest2"]["howmany"] == 0:
Expand All @@ -815,6 +810,7 @@ def check_for_empty_nest(
pass

def check_stack(self, tower):
"""Check a stack to see if there's room for another plate, returns True if there is room, False if not."""
# save z height of stack Z = -36
tower_z_height = -50
tower_z_bottom = -421.8625
Expand All @@ -831,8 +827,8 @@ def check_stack(self, tower):
else: # stack full
return False

# * Remove lid, (self, lidnest, plate_type), removes lid from plate in exchange, trash bool will throw lid into trash
def remove_lid(self, trash):
"""Remove lid, (self, lidnest, plate_type), removes lid from plate in exchange, trash bool will throw lid into trash"""
# move above plate exchange
self.set_speed(100)
self.open()
Expand Down Expand Up @@ -925,8 +921,8 @@ def remove_lid(self, trash):
self.labware[lid_nest]["type"] = self.labware["exchange"]["type"]
self.labware["exchange"]["has_lid"] = False

# * Plate on exchange, replace lid (self, plateinfo, lidnest)
def replace_lid(self):
"""Plate on exchange, replace lid (self, plateinfo, lidnest)"""
# find a lid
self.set_speed(100)
self.open()
Expand Down Expand Up @@ -991,8 +987,8 @@ def replace_lid(self):
self.labware[lid_nest]["howmany"] -= 1
self.labware["exchange"]["has_lid"] = True

# * Plate from exchange to stack (self, tower, plateinfo)
def plate_to_stack(self, tower, add_lid):
"""Plate from exchange to stack (self, tower, plateinfo)"""
# Move arm up and to neutral position to avoid hitting any objects
self.open()
self.set_speed(10)
Expand Down Expand Up @@ -1064,8 +1060,8 @@ def plate_to_stack(self, tower, add_lid):
self.labware["exchange"]["howmany"] -= 1
self.labware[tower]["howmany"] += 1

# * Remove lid from lidnest, throw away
def lidnest_to_trash(self, lidnest):
"""Remove lid from lidnest, throw away"""
# Move arm up and to neutral position to avoid hitting any objects
self.open()
self.set_speed(10)
Expand Down Expand Up @@ -1136,8 +1132,8 @@ def lidnest_to_trash(self, lidnest):
else:
print("NO LID IN NEST")

# * Remove plate from exchange, throw away
def plate_to_trash(self, add_lid):
"""Remove plate from exchange, throw away"""
# Move arm up and to neutral position to avoid hitting any objects
self.open()
self.set_speed(10)
Expand Down
Loading

0 comments on commit 9afac5a

Please sign in to comment.