From 0ef9f89a8f3ad8e9bb8ad1ed6ff0f8cecde12801 Mon Sep 17 00:00:00 2001 From: Shubham Vyas Date: Wed, 28 Jun 2023 14:00:41 +0200 Subject: [PATCH] moved motor_socket to class variable instead of instance variable to fix bugs Multiple motors on same can bus do not work unless either this is done or better filtering is implemented. Until then, multiple can bus is not supported. --- README.md | 4 ++-- setup.cfg | 2 +- src/motor_driver/canmotorlib.py | 30 ++++++++++++++++++------------ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 94dea6f..81a9653 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Install via: # Documentation -- Useful videos: +- Useful videos: - [From T-Motor](https://www.youtube.com/watch?v=hbqQCgebaF8) - [From Skyentific](https://www.youtube.com/watch?v=HzY9vzgPZkA) - [Motor Datasheets](https://store.cubemars.com/images/file/20220307/1646619452473352.pdf) @@ -177,6 +177,6 @@ To add a new constants configuration use the `change_motor_constants` function o # Known Issues -**Issue Fixed**: When having 2 motors on the CAN bus with either PCAN CAN-USB or ESD CAN-USB/2, sometimes the motors experience an initial short *kick/impulse* at when they are enabled again after being disabled. This was fixed. +Currently, the driver does not support multiple CAN busses i.e. multiple CAN2USB devices. The fix for this is in the works... As this is experimental software, there might be other unknown issues. diff --git a/setup.cfg b/setup.cfg index 1fe4755..bd7f75c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = mini-cheetah-motor-driver-socketcan -version = 0.4.2 +version = 0.4.3 author = Shubham Vyas author_email = Shubham.Vyas@dfki.de description = A Python Driver for MIT Mini-Cheetah Actuator which uses SocketCAN for communication. diff --git a/src/motor_driver/canmotorlib.py b/src/motor_driver/canmotorlib.py index 8e6cc29..b74af5f 100644 --- a/src/motor_driver/canmotorlib.py +++ b/src/motor_driver/canmotorlib.py @@ -179,6 +179,8 @@ class CanMotorController: Class for creating a Mini-Cheetah Motor Controller over CAN. Uses SocketCAN driver for communication. """ + can_socket_declared = False + motor_socket = None def __init__(self, can_socket="can0", motor_id=0x01, motor_type="AK80_6_V1p1", socket_timeout=0.05): """ @@ -210,16 +212,20 @@ def __init__(self, can_socket="can0", motor_id=0x01, motor_type="AK80_6_V1p1", s can_socket = (can_socket,) self.motor_id = motor_id - # create a raw socket and bind it to the given CAN interface - try: - self.motor_socket = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW) - self.motor_socket.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_LOOPBACK, 0) - self.motor_socket.bind(can_socket) - self.motor_socket.settimeout(socket_timeout) - print("Bound to: ", can_socket) - except Exception as e: - print("Unable to Connect to Socket Specified: ", can_socket) - print("Error:", e) + if not CanMotorController.can_socket_declared: + # create a raw socket and bind it to the given CAN interface + try: + CanMotorController.motor_socket = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW) + CanMotorController.motor_socket.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_LOOPBACK, 0) + CanMotorController.motor_socket.bind(can_socket) + CanMotorController.motor_socket.settimeout(socket_timeout) + print("Bound to: ", can_socket) + CanMotorController.can_socket_declared = True + except Exception as e: + print("Unable to Connect to Socket Specified: ", can_socket) + print("Error:", e) + elif CanMotorController.can_socket_declared: + print("Socket already available. Using: ", CanMotorController.motor_socket) # Initialize the command BitArrays for performance optimization self._p_des_BitArray = BitArray( @@ -241,7 +247,7 @@ def _send_can_frame(self, data): can_dlc = len(data) can_msg = struct.pack(can_frame_fmt_send, self.motor_id, can_dlc, data) try: - self.motor_socket.send(can_msg) + CanMotorController.motor_socket.send(can_msg) except Exception as e: print("Unable to Send CAN Frame.") print("Error: ", e) @@ -252,7 +258,7 @@ def _recv_can_frame(self): """ try: # The motor sends back only 6 bytes. - frame, addr = self.motor_socket.recvfrom(recvBytes) + frame, addr = CanMotorController.motor_socket.recvfrom(recvBytes) can_id, can_dlc, data = struct.unpack(can_frame_fmt_recv, frame) return can_id, can_dlc, data[:can_dlc] except Exception as e: