I am working on a python code involving two cameras(flir and logitech camera) and I am using usb relay to control light for each of the camera and getting this error inside motion_start. Relay 1 turns on but then the error comes. I have attached the code block where error comes. The Led indicator on camera does turn on
def motion_start(self):
check = self.initialize_devices()
if len(self.devices) < 3:
print(len(self.devices))
return None
self.move(Decimal(self.motion_params.x_cam2), Decimal(self.motion_params.y_cam2), Decimal(self.motion_params.z_cam2))
relay_controller = RelayApp()
relay_controller.get_Hid_USBRelay()
relay_controller.open_device()
camera_app = SecondaryCameraApp()
cap = camera_app.initialize_camera()
try:
relay_controller.turn_off_all_relays()
time.sleep(0.5)
relay_controller.turn_on_relay(1)
time.sleep(4) # Wait for 4 seconds
# Capture image using the secondary camera
frame = camera_app.capture_image(cap)
transformed_image = camera_app.apply_perspective_transform(frame)
relay_controller.turn_off_relay(1)
time.sleep(0.5)
relay_controller.turn_on_relay(2)
time.sleep(0.5)
relay_controller.turn_off_relay(2)
self.current_data.set_stop_acquisition(False)
for i in range(self.motion_params.y_steps):
if self.current_data.get_stop_acquisition():
print("Acquisition stopped in y loop.")
break
y_position = Decimal(self.motion_params.y_start + i * self.motion_params.y_increment)
print(f"New y_position: {y_position}")
for j in range(self.motion_params.x_steps):
if self.current_data.get_stop_acquisition():
print("Acquisition stopped in x loop.")
break
x_position = Decimal(self.motion_params.x_start + j * self.motion_params.x_increment)
print(f"New x_position: {x_position}")
if not self.motion_params.optimal_z_movement:
print(f"Calling z_movement_incremental for x: {x_position}, y: {y_position}")
self.z_movement_incremental(x_position, y_position, j)
else:
print(f"Calling z_movement_optimal for x: {x_position}, y: {y_position}")
self.z_movement_optimal(x_position, y_position, j)
if j == 0:
self.current_data.set_row_start_z(self.current_data.get_best_z())
print(f"Set row start z to: {self.current_data.get_best_z()}")
print("Homing")
self.move(Decimal(0.1), Decimal(0.1), Decimal(0.1))
print("Homing completed")
time.sleep(0.1)
self.update_positions()
except Exception as e:
print(f"Error during relay or camera control: {e}")
return None
finally:
cap.release() # Ensure the camera is released
relay_controller.close_device() # Ensure the relay device is closed
I had isolated the two classes SecondaryCameraApp and RelayApp in a separate python file with a Controller class then the code runs fine
Full error traceback
Building device list...
['26004899', '26004900']
['27003670']
['26004899', '26004900', '27003670']
['27003670', '26004900', '26004899']
Device Info: KDC101 DC Servo Drive
Device Info: KST101 Stepper Controller v3.1 1
Device Info: KST101 Stepper Controller v3.1 1
Vendor ID: 5824
Product ID: 1503
Move 25 20 0
Move time: 10.698481798171997
Turning off all relays...
Sending buffer: [0, 252, 0, 0, 0, 0, 0, 0, 1]
Command sent successfully.
Attempting to turn on relay 1...
Sending buffer: [0, 255, 1, 0, 0, 0, 0, 0, 1]
Command sent successfully.
Relay 1 turned on.
ERROR:root:Relay and camera control failed: 'module' object is not callable
Full code
Full code
Let me add a smaller version of the code that works
import os
import json
import cv2
import pywinusb.hid as hid
relay control
import numpy as np
from time import sleep, time
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
# RelayApp class
class RelayApp:
def __init__(self):
config = self.load_configuration()
self.vendor_id = int(config["lightcontrol"]["USB_CFG_VENDOR_ID"], 16)
self.device_id = int(config["lightcontrol"]["USB_CFG_DEVICE_ID"], 16)
self.hid_device = None
self.device = None
self.report = None
def load_configuration(self):
try:
file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'spinnaker_parameters.json')
with open(file_path, 'r') as file:
data = json.load(file)
return data
except FileNotFoundError:
logging.error(f"Configuration file not found: {file_path}")
raise
except json.JSONDecodeError:
logging.error(f"Error decoding JSON in file: {file_path}")
raise
def get_Hid_USBRelay(self):
filter = hid.HidDeviceFilter(vendor_id=self.vendor_id, product_id=self.device_id)
hid_device = filter.get_devices()
self.device = hid_device[0]
def open_device(self):
if self.device.is_active() and not self.device.is_opened():
self.device.open()
self.get_report()
def close_device(self):
if self.device.is_active() and self.device.is_opened():
self.device.close()
def get_report(self):
if not self.device.is_active():
self.report = None
for rep in self.device.find_output_reports() + self.device.find_feature_reports():
self.report = rep
def write_row_data(self, buffer):
if self.report is not None:
try:
logging.info(f"Sending buffer: {buffer}")
self.report.send(raw_data=buffer)
logging.info("Command sent successfully.")
return True
except Exception as e:
logging.error(f"Error sending command: {e}")
else:
logging.error("No report available to send data.")
return False
def turn_on_relay(self, relay_number):
logging.info(f"Attempting to turn on relay {relay_number}...")
if relay_number not in [1, 2]:
logging.error("Invalid relay number.")
return
success = self.write_row_data([0, 0xFF, relay_number, 0, 0, 0, 0, 0, 1])
if success:
logging.info(f"Relay {relay_number} turned on.")
else:
logging.error(f"Failed to send command to turn on relay {relay_number}.")
def turn_off_relay(self, relay_number):
logging.info(f"Turning off relay {relay_number}...")
self.write_row_data([0, 0xFD, relay_number, 0, 0, 0, 0, 0, 1])
def turn_off_all_relays(self):
logging.info("Turning off all relays...")
self.write_row_data([0, 0xFC, 0, 0, 0, 0, 0, 0, 1])
# SecondaryCameraApp class
class SecondaryCameraApp:
def __init__(self):
config = self.load_configuration()
self.camera_index = int(config["secondarycamera"]["index"])
self.width = int(config["secondarycamera"]["width"])
self.height = int(config["secondarycamera"]["height"])
self.exposure = int(config["secondarycamera"]["exposure"])
self.focus = int(config["secondarycamera"]["focus"])
self.capture_path = config["secondarycamera"]["capture_path"]
self.transformed_image_path = config["secondarycamera"]["transformed_image_path"]
self.tl = config["secondarycamera"]["tl"]
self.tr = config["secondarycamera"]["tr"]
self.bl = config["secondarycamera"]["bl"]
self.br = config["secondarycamera"]["br"]
def load_configuration(self):
try:
file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'spinnaker_parameters.json')
with open(file_path, 'r') as file:
data = json.load(file)
return data
except FileNotFoundError:
logging.error(f"Configuration file not found: {file_path}")
raise
except json.JSONDecodeError:
logging.error(f"Error decoding JSON in file: {file_path}")
raise
def initialize_camera(self):
cap = cv2.VideoCapture(self.camera_index, cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, self.width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self.height)
cap.set(cv2.CAP_PROP_FOCUS, self.focus)
cap.set(cv2.CAP_PROP_EXPOSURE, self.exposure)
return cap
def capture_image(self, cap):
start_time = time()
ret, frame = cap.read()
end_time = time()
logging.info(f"Time taken to capture the image: {end_time - start_time:.4f} seconds")
if ret:
cv2.imwrite(self.capture_path, frame)
logging.info(f"Image captured and saved as {self.capture_path}")
else:
logging.error("Failed to capture the image")
return frame
def apply_perspective_transform(self, image):
if image is None:
logging.error("No image to transform")
return None
pts1 = np.float32([self.tl, self.tr, self.bl, self.br])
width, height = 1200, 420
pts2 = np.float32([[0, 0], [width, 0], [0, height], [width, height]])
M = cv2.getPerspectiveTransform(pts1, pts2)
transformed_image = cv2.warpPerspective(image, M, (width, height))
cv2.imwrite(self.transformed_image_path, transformed_image)
logging.info(f"Transformed image saved as {self.transformed_image_path}")
return transformed_image
# SystemController class
class SystemController:
def __init__(self):
self.relay = RelayApp()
self.camera = SecondaryCameraApp()
def control_relay(self):
try:
self.relay.get_Hid_USBRelay()
self.relay.open_device()
self.relay.turn_off_all_relays()
sleep(0.5)
self.relay.turn_on_relay(1)
sleep(6)
self.relay.turn_off_relay(1)
sleep(0.5)
self.relay.turn_on_relay(2)
sleep(0.5)
self.relay.turn_off_all_relays()
except Exception as e:
logging.error(f"Relay control failed: {e}")
finally:
self.relay.close_device()
def control_camera(self):
try:
cap = self.camera.initialize_camera()
ret, frame = cap.read()
if not ret:
logging.error("Failed to grab frame")
return
frame = self.camera.capture_image(cap)
if frame is not None:
self.camera.apply_perspective_transform(frame)
except Exception as e:
logging.error(f"Camera control failed: {e}")
finally:
cap.release()
cv2.destroyAllWindows()
def main(self):
start_time = time()
self.control_relay()
self.control_camera()
end_time = time()
logging.info(f"Total execution time: {end_time - start_time:.2f} seconds")
if __name__ == "__main__":
system_controller = SystemController()
system_controller.main()
Output (this works)
This will turn off relays and then turn one by one the click image and then apply transformaion and save the image
I am trying to incorporate this into the main code. Something is happening when camera is called because LED indicator does turn on after that the error comes
Hamza Hasan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
12
While I was going through the code I found the problem it was inconsistency in the import of time module in capture_image inside SecondaryCameraApp in the both versions. Got it fixed. Thankyou
Hamza Hasan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.