@@ -7,7 +7,7 @@ class Tracking:
7
7
TRACKING_THRESHOLD = (50 , 50 )
8
8
VIDEO_SIZE = (640 , 480 ) # Pixel dimensions of the image
9
9
VIDEO_CENTER = (VIDEO_SIZE [0 ] / 2 , VIDEO_SIZE [1 ] / 2 )
10
- PIXELS_PER_DEG = (4.4 , - 2.6 ) # Set during calibration session. Run calibrate_servo_movement() to recalibrate
10
+ PIXELS_PER_DEG = (- 12.5 , 0.7 ) # Set during calibration session. Run calibrate_servo_movement() to recalibrate
11
11
12
12
def __init__ (self , ** kwargs ):
13
13
self .active = kwargs .get ('active' , True )
@@ -78,11 +78,12 @@ def track_match(self, match):
78
78
print (f"Moving Y: { y_move } ({ match ['distance_y' ]} )" )
79
79
80
80
if x_move :
81
- pub .sendMessage ('servo:pan:mv' , percentage = - x_move )
82
- if y_move :
83
- pub .sendMessage ('servo:tilt:mv' , percentage = - y_move )
81
+ pub .sendMessage ('servo:pan:mv' , percentage = x_move )
82
+ # if y_move:
83
+ # pub.sendMessage('servo:tilt:mv', percentage=y_move)
84
84
85
- move_time = abs (max (x_move , y_move )) / 5
85
+ move_time = max (abs (max (x_move , y_move )) / 50 , 1 ) # min 1 second
86
+ print (f"Move time: { move_time } " )
86
87
stop_moving = Thread (target = self .debounce , args = (move_time ,))
87
88
stop_moving .start ()
88
89
@@ -109,70 +110,80 @@ def _get_area(bbox):
109
110
return float (x2 - x ) * float (y2 - y )
110
111
return 0
111
112
112
- def calibrate_servo_movement (self , match = None , servo_move_pct = 10 ):
113
+ def calibrate_servo_movement (self , axis = 0 , label = None , match = None , servo_move_pct = 10 ):
113
114
"""
114
115
Calibrate the servos to determine the degree range for pan (x-axis) and tilt (y-axis).
115
116
Moves the servo a preset percentage, then calculates the degree-per-pixel ratio.
116
117
117
118
:param match: The match (object) to track.
118
119
:param servo_move_pct: Percentage of the servo's range to move for calibration.
119
120
"""
120
- if match == None :
121
- matches = self ._get_latest_detections ()
122
- if len (matches ) > 0 :
123
- match = matches [0 ]
121
+ match = self ._get_a_match (label )
124
122
125
123
if match == None :
126
124
print ('Could not find match, skipping calibration' )
127
125
return
128
126
# Get the initial position of the object
129
- (x , y , x2 , y2 ) = match ['bbox' ]
130
- initial_center_x = (x + x2 ) / 2
131
- initial_center_y = (y + y2 ) / 2
127
+ # (x, y, x2, y2) = match['bbox']
128
+ # initial_center_x = (x + x2) / 2
129
+ # initial_center_y = (y + y2) / 2
132
130
133
131
# Move the servos a preset percentage
134
- pub .sendMessage ('servo:pan:mv' , percentage = servo_move_pct )
135
- pub .sendMessage ('servo:tilt:mv' , percentage = servo_move_pct )
132
+ if axis == 0 :
133
+ pub .sendMessage ('servo:pan:mv' , percentage = servo_move_pct )
134
+ else :
135
+ pub .sendMessage ('servo:tilt:mv' , percentage = servo_move_pct )
136
136
137
137
# Wait for the servo movement to complete (e.g., debounce time)
138
138
sleep (5 ) # This can be adjusted as per servo speed
139
139
140
140
# Re-detect the object after the movement
141
- new_matches = self ._get_latest_detections () # You need a method to get the latest matches
142
- new_match = self ._find_same_match (new_matches , match )
141
+ new_match = None
142
+ for i in range (5 ):
143
+ new_matches = self ._get_latest_detections ()
144
+ if len (new_matches ) > 0 :
145
+ new_match = self ._find_same_match (new_matches , match )
143
146
144
147
if new_match :
145
148
# Get the new position of the object
146
- (nx , ny , nx2 , ny2 ) = new_match ['bbox' ]
147
- new_center_x = (nx + nx2 ) / 2
148
- new_center_y = (ny + ny2 ) / 2
149
+ # (nx, ny, nx2, ny2) = new_match['bbox']
150
+ # new_center_x = (nx + nx2) / 2
151
+ # new_center_y = (ny + ny2) / 2
149
152
150
153
# Calculate the pixel movement
151
- x_pixel_movement = new_center_x - initial_center_x
152
- y_pixel_movement = new_center_y - initial_center_y
153
-
154
- print (servo_move_pct )
155
- print (x_pixel_movement )
156
-
154
+ # if axis == 0:
155
+ # pixel_movement = new_center_x - initial_center_x
156
+ # else:
157
+ # pixel_movement = new_center_y - initial_center_y
157
158
158
159
# Calculate the degrees moved
159
- pixels_per_percent_x = x_pixel_movement / servo_move_pct
160
- pixels_per_percent_y = y_pixel_movement / servo_move_pct
161
- print (pixels_per_percent_x )
160
+ # pixels_per_percent = pixel_movement / servo_move_pct
161
+ if axis == 0 :
162
+ dist = match ['distance_x' ] - new_match ['distance_x' ]
163
+ else :
164
+ dist = match ['distance_y' ] - new_match ['distance_y' ]
165
+ dist_ppc = dist / servo_move_pct
162
166
163
- Tracking .PIXELS_PER_DEG = (pixels_per_percent_x ,
164
- pixels_per_percent_y )
165
-
166
- print (f"Calibration complete: New PIXELS_PER_DEG values: { Tracking .PIXELS_PER_DEG } " )
167
- sleep (5 )
167
+ newvals = list (Tracking .PIXELS_PER_DEG )
168
+ newvals [axis ] = dist_ppc
169
+ Tracking .PIXELS_PER_DEG = tuple (newvals )
170
+
171
+ # print(f"Initial Dist: {match['distance_x']}, New Dist: {new_match['distance_x']}, Diff: {dist}, Px/%: {dist_ppc}")
172
+ # print(f'Initial: {initial_center_x}, New: {new_center_x}, Diff: {pixel_movement}, Px/%: {pixels_per_percent}')
168
173
169
- self . track_match ( new_match )
174
+ print ( f"Calibration complete: New PIXELS_PER_DEG assigned for axis { axis } . values: { Tracking . PIXELS_PER_DEG } " )
170
175
171
- print (f"Calibration: Centering on target: { new_match ['category' ]} " )
172
176
else :
173
177
print ('No second match to calibrate against!' )
174
178
175
179
180
+ def _get_a_match (self , label ):
181
+ for i in range (5 ):
182
+ matches = self ._get_latest_detections ()
183
+ if len (matches ) > 0 :
184
+ for m in matches :
185
+ if m ['category' ] == label :
186
+ return m
176
187
177
188
def _get_latest_detections (self ):
178
189
return self .camera .scan (1 )
@@ -190,7 +201,7 @@ def is_similar_bbox(bbox1, bbox2, threshold=0.2):
190
201
abs (y1 - y2 ) < threshold * Tracking .VIDEO_SIZE [1 ]
191
202
192
203
for match in matches :
193
- if is_similar_bbox (original_match ['bbox' ], match ['bbox' ]):
204
+ if original_match [ 'category' ] == match [ 'category' ] or is_similar_bbox (original_match ['bbox' ], match ['bbox' ]):
194
205
return match
195
206
return None
196
207
@@ -201,7 +212,8 @@ def is_similar_bbox(bbox1, bbox2, threshold=0.2):
201
212
tracking = Tracking (camera = mycam )
202
213
203
214
# Calibrate the servo range with a sample match
204
- tracking .calibrate_servo_movement ()
215
+ tracking .calibrate_servo_movement (0 )
216
+ tracking .calibrate_servo_movement (1 )
205
217
206
218
while True :
207
219
mycam .scan (1 )
0 commit comments