|
24 | 24 | class FrameGrabber: |
25 | 25 | """Dedicated thread for frame capture to improve performance""" |
26 | 26 |
|
27 | | - def __init__(self, node=None): |
| 27 | + def __init__(self, node=None, config=None): |
28 | 28 | self.node = node |
| 29 | + self.config = config or {} |
| 30 | + |
29 | 31 | # Camera properties |
30 | 32 | self.camera = None |
31 | 33 | self.camera_index = 0 |
@@ -77,21 +79,16 @@ def __init__(self, node=None): |
77 | 79 | # Face detection |
78 | 80 | self.enable_face_detection = True |
79 | 81 | self.face_detector = FaceDetector( |
80 | | - confidence_threshold=0.5, |
81 | | - smoothing_factor=0.4, |
| 82 | + confidence_threshold=self.config.get('face_confidence_threshold', 0.5), |
| 83 | + smoothing_factor=self.config.get('face_smoothing_factor', 0.4), |
82 | 84 | logger=self.node.get_logger() if self.node else None |
83 | 85 | ) |
84 | 86 |
|
85 | | - # # Get parameters |
86 | | - # self.invert_x = self.get_parameter('invert_x').value |
87 | | - # self.invert_y = self.get_parameter('invert_y').value |
88 | | - # self.eye_range = self.get_parameter('eye_range').value |
89 | | - |
90 | | - # TODO: Added this hot fix |
91 | | - self.invert_x = False |
92 | | - self.invert_y = False |
93 | | - # self.eye_range = 3.0 |
94 | | - self.eye_range = 1.0 # The constraint for the values of the eye movement in the UI |
| 87 | + # Eye movement parameters from configuration |
| 88 | + self.invert_x = self.config.get('invert_x', False) |
| 89 | + self.invert_y = self.config.get('invert_y', False) |
| 90 | + self.eye_range = self.config.get('eye_range', 1.0) |
| 91 | + self.eye_sensitivity = self.config.get('eye_sensitivity', 1.5) |
95 | 92 |
|
96 | 93 | # ROS publishers for face data and images |
97 | 94 | if self.node: |
@@ -223,7 +220,7 @@ def publish_face_position(self, faces): |
223 | 220 | frame_width=self.frame_width, |
224 | 221 | frame_height=self.frame_height, |
225 | 222 | eye_range=self.eye_range, |
226 | | - sensitivity=1.5, |
| 223 | + sensitivity=self.eye_sensitivity, |
227 | 224 | invert_x=self.invert_x, |
228 | 225 | invert_y=self.invert_y, |
229 | 226 | logger=self.node.get_logger() if self.node else None |
@@ -619,36 +616,55 @@ def __init__(self): |
619 | 616 | super().__init__('coffee_camera_node') |
620 | 617 | self.get_logger().info('Camera node is starting...') |
621 | 618 |
|
622 | | - # Initialize frame grabber for camera processing |
623 | | - self.frame_grabber = FrameGrabber(self) |
624 | | - |
625 | | - # Set up ROS control interface for separated UI communication |
626 | | - self._setup_ros_control_interface() |
627 | | - |
628 | 619 | # Camera state tracking |
629 | 620 | self.available_cameras = [] |
630 | 621 | self.current_camera_index = -1 |
631 | 622 | self.high_quality = False |
632 | 623 | self.face_detection_enabled = True |
633 | 624 |
|
634 | | - # # Add parameters for mapping |
635 | | - # self.declare_parameter('invert_x', False) # Default FALSE for correct eye movement |
636 | | - # self.declare_parameter('invert_y', False) # Default FALSE for correct eye movement |
637 | | - # self.declare_parameter('eye_range', 3.0) # Max range for eye movement (-3.0 to 3.0) |
638 | | - |
639 | | - # # Get parameters |
640 | | - # self.invert_x = self.get_parameter('invert_x').value |
641 | | - # self.invert_y = self.get_parameter('invert_y').value |
642 | | - # self.eye_range = self.get_parameter('eye_range').value |
643 | | - |
644 | | - self.invert_x = False |
645 | | - self.invert_y = False |
646 | | - # self.eye_range = 3.0 |
647 | | - self.eye_range = 1.0 # The constraint for the values of the eye movement in the UI |
| 625 | + # Declare ROS parameters for configuration |
| 626 | + self._declare_parameters() |
| 627 | + |
| 628 | + # Get parameter values |
| 629 | + self._load_parameters() |
| 630 | + |
| 631 | + # Initialize frame grabber for camera processing |
| 632 | + config = { |
| 633 | + 'face_confidence_threshold': self.face_confidence_threshold, |
| 634 | + 'face_smoothing_factor': self.face_smoothing_factor, |
| 635 | + 'eye_range': self.eye_range, |
| 636 | + 'eye_sensitivity': self.eye_sensitivity, |
| 637 | + 'invert_x': self.invert_x, |
| 638 | + 'invert_y': self.invert_y |
| 639 | + } |
| 640 | + self.frame_grabber = FrameGrabber(self, config) |
| 641 | + |
| 642 | + # Set up ROS control interface for separated UI communication |
| 643 | + self._setup_ros_control_interface() |
648 | 644 |
|
649 | 645 | # Initialize camera system |
650 | 646 | self.scan_cameras() |
651 | 647 |
|
| 648 | + def _declare_parameters(self): |
| 649 | + """Declare ROS parameters with default values""" |
| 650 | + # Core parameters that were previously hard-coded |
| 651 | + self.declare_parameter('face_confidence_threshold', 0.5) |
| 652 | + self.declare_parameter('face_smoothing_factor', 0.4) |
| 653 | + self.declare_parameter('eye_range', 1.0) |
| 654 | + self.declare_parameter('eye_sensitivity', 1.5) |
| 655 | + self.declare_parameter('invert_x', False) |
| 656 | + self.declare_parameter('invert_y', False) |
| 657 | + |
| 658 | + def _load_parameters(self): |
| 659 | + """Load parameter values from ROS parameter server""" |
| 660 | + self.face_confidence_threshold = self.get_parameter('face_confidence_threshold').value |
| 661 | + self.face_smoothing_factor = self.get_parameter('face_smoothing_factor').value |
| 662 | + self.eye_range = self.get_parameter('eye_range').value |
| 663 | + self.eye_sensitivity = self.get_parameter('eye_sensitivity').value |
| 664 | + self.invert_x = self.get_parameter('invert_x').value |
| 665 | + self.invert_y = self.get_parameter('invert_y').value |
| 666 | + |
| 667 | + |
652 | 668 | def scan_cameras(self): |
653 | 669 | """Scan for available cameras""" |
654 | 670 | self.get_logger().info("Scanning for cameras...") |
@@ -753,6 +769,7 @@ def _setup_ros_control_interface(self): |
753 | 769 | self.state_query_sub = self.create_subscription( |
754 | 770 | String, '/coffee_bot/camera/query/state', self._on_state_query, 10) |
755 | 771 |
|
| 772 | + |
756 | 773 | self.get_logger().info('ROS control interface setup complete') |
757 | 774 |
|
758 | 775 | def _on_camera_select_command(self, msg): |
@@ -820,6 +837,7 @@ def _on_diagnostics_request(self, msg): |
820 | 837 |
|
821 | 838 | self.get_logger().info('Published diagnostics information') |
822 | 839 |
|
| 840 | + |
823 | 841 | def _generate_diagnostics_info(self): |
824 | 842 | """Generate comprehensive diagnostics information""" |
825 | 843 | import os |
|
0 commit comments