11 from std_msgs.msg
import Int32
12 from sensor_msgs.msg
import Image
13 from cv_bridge
import CvBridge, CvBridgeError
14 from geometry_msgs.msg
import Point
18 from control_msgs.msg
import (
19 FollowJointTrajectoryAction,
20 FollowJointTrajectoryGoal,
21 JointTrajectoryControllerState
23 from trajectory_msgs.msg
import JointTrajectoryPoint
35 self.
_image_pub = rospy.Publisher(
"~output_image", Image, queue_size=1)
50 input_image = self.
_bridge.imgmsg_to_cv2(ros_image,
"bgr8")
51 except CvBridgeError
as e:
60 input_image = self.
_bridge.imgmsg_to_cv2(ros_image,
"passthrough")
61 except CvBridgeError
as e:
70 if output_image
is not False:
80 object_center = Point(
86 translated_point = Point()
87 translated_point.x = object_center.x - self.
_image_shape.x * 0.5
88 translated_point.y = -(object_center.y - self.
_image_shape.y * 0.5)
91 normalized_point = Point()
93 normalized_point.x = translated_point.x / (self.
_image_shape.x * 0.5)
94 normalized_point.y = translated_point.y / (self.
_image_shape.y * 0.5)
96 return normalized_point
105 MIN_OBJECT_SIZE = 10000
106 MAX_OBJECT_SIZE = 80000
125 if output_image
is None:
130 for i, depth
in enumerate(DETECTION_DEPTH):
132 mask = cv2.inRange(input_depth_image, depth[0], depth[1])
136 contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
138 _, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
142 for contour
in contours:
143 approx = cv2.convexHull(contour)
144 rect = cv2.boundingRect(approx)
149 rect = max(rects, key=(
lambda x: x[2] * x[3]))
151 rect_size = rect[2] * rect[3]
154 if rect_size > MIN_OBJECT_SIZE
and rect_size < MAX_OBJECT_SIZE:
156 cv2.rectangle(output_image,
158 (rect[0] + rect[2], rect[1] + rect[3]),
159 RECT_COLOR[i], thickness=2)
165 object_depth = input_depth_image[
166 rect[1]:rect[1]+rect[3],
167 rect[0]:rect[0]+rect[2]]
173 (rect[0], rect[1]+30),
174 cv2.FONT_HERSHEY_SIMPLEX,
184 FollowJointTrajectoryAction)
185 self.
__client.wait_for_server(rospy.Duration(5.0))
186 if not self.
__client.wait_for_server(rospy.Duration(5.0)):
187 rospy.logerr(
"Action Server Not Found")
188 rospy.signal_shutdown(
"Action Server not found")
191 self.
_state_sub = rospy.Subscriber(
"/sciurus17/controller3/neck_controller/state",
203 yaw_radian = state.actual.positions[0]
204 pitch_radian = state.actual.positions[1]
222 def set_angle(self, yaw_angle, pitch_angle, goal_secs=1.0e-9):
224 goal = FollowJointTrajectoryGoal()
225 goal.trajectory.joint_names = [
"neck_yaw_joint",
"neck_pitch_joint"]
227 yawpoint = JointTrajectoryPoint()
228 yawpoint.positions.append(yaw_angle)
229 yawpoint.positions.append(pitch_angle)
230 yawpoint.time_from_start = rospy.Duration(goal_secs)
231 goal.trajectory.points.append(yawpoint)
234 self.
__client.wait_for_result(rospy.Duration(0.1))
240 neck.set_angle(math.radians(0), math.radians(0), 3.0)
246 rospy.on_shutdown(hook_shutdown)
254 INITIAL_YAW_ANGLE = 0
255 INITIAL_PITCH_ANGLE = 0
261 MIN_PITCH_ANGLE = -70
265 OPERATION_GAIN_X = 5.0
266 OPERATION_GAIN_Y = 5.0
269 RESET_OPERATION_ANGLE = 3
273 while not neck.state_received():
275 yaw_angle = neck.get_current_yaw()
276 pitch_angle = neck.get_current_pitch()
279 detection_timestamp = rospy.Time.now()
281 while not rospy.is_shutdown():
283 object_position = object_tracker.get_object_position()
285 if object_tracker.object_detected():
286 detection_timestamp = rospy.Time.now()
289 lost_time = rospy.Time.now() - detection_timestamp
291 if lost_time.to_sec() > 1.0:
296 if math.fabs(object_position.x) > THRESH_X:
297 yaw_angle += -object_position.x * OPERATION_GAIN_X
299 if math.fabs(object_position.y) > THRESH_Y:
300 pitch_angle += object_position.y * OPERATION_GAIN_Y
303 if yaw_angle > MAX_YAW_ANGLE:
304 yaw_angle = MAX_YAW_ANGLE
305 if yaw_angle < MIN_YAW_ANGLE:
306 yaw_angle = MIN_YAW_ANGLE
308 if pitch_angle > MAX_PITCH_ANGLE:
309 pitch_angle = MAX_PITCH_ANGLE
310 if pitch_angle < MIN_PITCH_ANGLE:
311 pitch_angle = MIN_PITCH_ANGLE
315 diff_yaw_angle = yaw_angle - INITIAL_YAW_ANGLE
316 if math.fabs(diff_yaw_angle) > RESET_OPERATION_ANGLE:
317 yaw_angle -= math.copysign(RESET_OPERATION_ANGLE, diff_yaw_angle)
319 yaw_angle = INITIAL_YAW_ANGLE
321 diff_pitch_angle = pitch_angle - INITIAL_PITCH_ANGLE
322 if math.fabs(diff_pitch_angle) > RESET_OPERATION_ANGLE:
323 pitch_angle -= math.copysign(RESET_OPERATION_ANGLE, diff_pitch_angle)
325 pitch_angle = INITIAL_PITCH_ANGLE
327 neck.set_angle(math.radians(yaw_angle), math.radians(pitch_angle))
332 if __name__ ==
'__main__':
333 rospy.init_node(
"depth_camera_tracking")
def _image_callback(self, ros_image)
def get_object_position(self)
def get_current_yaw(self)
def object_detected(self)
def set_angle(self, yaw_angle, pitch_angle, goal_secs=1.0e-9)
def get_current_pitch(self)
def _depth_callback(self, ros_image)
def _state_callback(self, state)
def _detect_object(self, input_depth_image)