class Party:
    def __init__(self):

        #		self.bridge = CvBridge()
        #		self.image_received = False
        self.encLeft_received = False
        self.encRight_received = False
        self.apriltagStatus_received = False
        self.apriltagID_received = False

        self.apriltag_detection_ID = None

        self.taskONE = False
        self.taskTWO = False

        self.MAX_LIN_VEL = 0.02
        self.MAX_ANG_VEL = 0.03

        # set PID values for panning
        self.panP = 0.5
        self.panI = 0
        self.panD = 0

        # set PID values for tilting
        self.tiltP = 0.5
        self.tiltI = 0
        self.tiltD = 0.5

        # create a PID and initialize it
        self.panPID = PID(self.panP, self.panI, self.panD)
        self.tiltPID = PID(self.tiltP, self.tiltI, self.tiltD)

        self.panPID.initialize()
        self.tiltPID.initialize()

        self.partyTwist = Twist()
        self.resetLeft = Bool()
        self.resetRight = Bool()

        rospy.logwarn("Party Node [ONLINE]...")

        # rospy shutdown
        rospy.on_shutdown(self.cbShutdown)

        # Subscribe to Int64 msg
        self.encLeft_topic = "/val_encLeft"
        self.encLeft_sub = rospy.Subscriber(self.encLeft_topic, Int64,
                                            self.cbEncoderLeft)

        # Subscribe to Int64 msg
        self.encRight_topic = "/val_encRight"
        self.encRight_sub = rospy.Subscriber(self.encRight_topic, Int64,
                                             self.cbEncoderRight)

        # Subscribe to Bool msg
        self.apriltagStatus_topic = "/apriltag_detection_status"
        self.apriltagStatus_sub = rospy.Subscriber(
            self.apriltagStatus_topic, Bool, self.cbAprilTagDetectionStatus)

        # Subscribe to Int64 msg
        self.apriltagID_topic = "/apriltag_detection_ID"
        self.apriltagID_sub = rospy.Subscriber(self.apriltagID_topic, Int64,
                                               self.cbAprilTagDetectionID)

        # Subscribe to objCenter msg
        self.objCoord_topic = "/objCoord"
        self.objCoord_sub = rospy.Subscriber(self.objCoord_topic, objCoord,
                                             self.cbObjCoord)

        # Subscribe to CameraInfo msg
        self.telloCameraInfo_topic = "/cv_camera/camera_info_converted"
        self.telloCameraInfo_sub = rospy.Subscriber(self.telloCameraInfo_topic,
                                                    CameraInfo,
                                                    self.cbCameraInfo)

        # Publish to Twist msg
        self.partyTwist_topic = "/cmd_vel"
        self.partyTwist_pub = rospy.Publisher(self.partyTwist_topic,
                                              Twist,
                                              queue_size=10)

        # Subscribe to Int64 msg
        self.rstEncLeft_topic = "/rstEncLeft"
        self.rstEncLeft_pub = rospy.Publisher(self.rstEncLeft_topic,
                                              Bool,
                                              queue_size=10)

        # Subscribe to Int64 msg
        self.rstEncRight_topic = "/rstEncRight"
        self.rstEncRight_pub = rospy.Publisher(self.rstEncRight_topic,
                                               Bool,
                                               queue_size=10)

        # Allow up to one second to connection
        rospy.sleep(1)

    # Get Encoder reading
    def cbEncoderLeft(self, msg):

        try:
            self.val_encLeft = msg.data

        except KeyboardInterrupt as e:
            print(e)

        if self.val_encLeft is not None:
            self.encLeft_received = True
        else:
            self.encLeft_received = False

    # Get Encoder reading
    def cbEncoderRight(self, msg):

        try:
            self.val_encRight = msg.data

        except KeyboardInterrupt as e:
            print(e)

        if self.val_encRight is not None:
            self.encRight_received = True
        else:
            self.encRight_received = False

    # Get AprilTagDetectionStatus reading
    def cbAprilTagDetectionStatus(self, msg):

        try:
            self.apriltag_detection_status = msg.data

        except KeyboardInterrupt as e:
            print(e)

        if self.apriltag_detection_status is not None:
            self.apriltagStatus_received = True
        else:
            self.apriltagStatus_received = False

    # Get AprilTagDetectionID reading
    def cbAprilTagDetectionID(self, msg):

        try:
            self.apriltag_detection_ID = msg.data

        except KeyboardInterrupt as e:
            print(e)

        if self.apriltag_detection_ID is not None:
            self.apriltagID_received = True
        else:
            self.apriltagID_received = False

    # Convert image to OpenCV format
    def cbCameraInfo(self, msg):

        self.imgWidth = msg.width
        self.imgHeight = msg.height

    # Convert image to OpenCV format
    def cbObjCoord(self, msg):

        self.objectCoordX = msg.centerX
        self.objectCoordY = msg.centerY

    # Main #
    def cbParty(self):

        if self.apriltag_detection_ID == 0:
            self.taskONE = True
        elif self.apriltag_detection_ID == 1 and self.taskONE == False:
            self.taskTWO = True
        else:
            self.cbStop()
            rospy.logwarn("Waiting For Instruction!")

        # Task 1: Search for the ArptilTag
        if self.taskONE == True:
            if (self.apriltag_detection_status == True
                    and self.apriltag_detection_ID != 0
                ) or self.val_encLeft >= 1000:
                self.cbStop
                self.resetLeft.data = True
                self.rstEncLeft_pub.publish(self.resetLeft)
                self.resetRight.data = True
                self.rstEncRight_pub.publish(self.resetRight)
                self.taskONE = False
            else:
                self.cbRotateR()

        # Task 2: Detected AprilTag ID: 1 and Tracking
        if self.taskTWO == True:
            if self.apriltag_detection_status == True and self.apriltag_detection_ID == 1:
                self.cbCallErr()
            else:
                self.taskTWO = False

    def cbAprilTag(self):

        self.cbPIDerr()

    # show information callback
    def cbPIDerr(self):

        self.panErr, self.panOut = self.cbPIDprocess(self.panPID,
                                                     self.objectCoordX,
                                                     self.imgWidth // 2)
        self.tiltErr, self.tiltOut = self.cbPIDprocess(self.tiltPID,
                                                       self.objectCoordY,
                                                       self.imgHeight // 2)

    def cbPIDprocess(self, pid, objCoord, centerCoord):

        # calculate the error
        error = centerCoord - objCoord

        # update the value
        output = pid.update(error)

        return error, output

    def cbCallErr(self):
        self.cbAprilTag()

        panSpeed = mapped(abs(self.panOut), 0, self.imgWidth // 2, 0,
                          self.MAX_LIN_VEL)
        tiltSpeed = mapped(abs(self.tiltOut), 0, self.imgHeight // 2, 0,
                           self.MAX_ANG_VEL)

        panSpeed = self.constrain(panSpeed, -self.MAX_LIN_VEL,
                                  self.MAX_LIN_VEL)
        tiltSpeed = self.constrain(tiltSpeed, -self.MAX_ANG_VEL,
                                   self.MAX_ANG_VEL)

        if self.tiltErr > 10:
            self.partyTwist.linear.x = 0.0
            self.partyTwist.linear.y = 0.0
            self.partyTwist.linear.z = 0.0

            self.partyTwist.angular.x = 0.0
            self.partyTwist.angular.y = 0.0
            self.partyTwist.angular.z = -tiltSpeed

        elif self.tiltErr < -10:
            self.partyTwist.linear.x = 0.0
            self.partyTwist.linear.y = 0.0
            self.partyTwist.linear.z = 0.0

            self.partyTwist.angular.x = 0.0
            self.partyTwist.angular.y = 0.0
            self.partyTwist.angular.z = tiltSpeed
        else:
            self.partyTwist.linear.x = 0.03
            self.partyTwist.linear.y = 0.0
            self.partyTwist.linear.z = 0.0

            self.partyTwist.angular.x = 0.0
            self.partyTwist.angular.y = 0.0
            self.partyTwist.angular.z = 0.0

        self.partyTwist_pub.publish(self.partyTwist)

    def constrain(self, input, low, high):
        if input < low:
            input = low
        elif input > high:
            input = high
        else:
            input = input

        return input

    def cbMove(self):

        self.partyTwist.linear.x = 0.02
        self.partyTwist.linear.y = 0.0
        self.partyTwist.linear.z = 0.0

        self.partyTwist.angular.x = 0.0
        self.partyTwist.angular.y = 0.0
        self.partyTwist.angular.z = 0.0

        self.partyTwist_pub.publish(self.partyTwist)

    def cbStop(self):

        self.partyTwist.linear.x = 0.0
        self.partyTwist.linear.y = 0.0
        self.partyTwist.linear.z = 0.0

        self.partyTwist.angular.x = 0.0
        self.partyTwist.angular.y = 0.0
        self.partyTwist.angular.z = 0.0

        self.partyTwist_pub.publish(self.partyTwist)

#		rospy.logwarn("STOP!")

    def cbRotateR(self):

        self.partyTwist.linear.x = 0.0
        self.partyTwist.linear.y = 0.0
        self.partyTwist.linear.z = 0.0

        self.partyTwist.angular.x = 0.0
        self.partyTwist.angular.y = 0.0
        self.partyTwist.angular.z = -0.02

        self.partyTwist_pub.publish(self.partyTwist)


#		rospy.logwarn("TURN RIGHT!")

# rospy shutdown callback

    def cbShutdown(self):

        rospy.logerr("Party Node [OFFLINE]...")

        self.partyTwist.linear.x = 0.0
        self.partyTwist.linear.y = 0.0
        self.partyTwist.linear.z = 0.0

        self.partyTwist.angular.x = 0.0
        self.partyTwist.angular.y = 0.0
        self.partyTwist.angular.z = 0.0

        self.partyTwist_pub.publish(self.partyTwist)
Exemple #2
0
class CameraAprilTag:
    def __init__(self):

        self.bridge = CvBridge()
        self.detector = apriltag.Detector()
        self.objectCoord = objCoord()
        self.telloCmdVel = Twist()

        self.image_received = False

        self.MAX_LIN_VEL = 0.005
        self.MAX_ANG_VEL = 0.03

        # set PID values for panning
        self.panP = 0.5
        self.panI = 0
        self.panD = 0

        # set PID values for tilting
        self.tiltP = 1
        self.tiltI = 0
        self.tiltD = 0

        # create a PID and initialize it
        self.panPID = PID(self.panP, self.panI, self.panD)
        self.tiltPID = PID(self.tiltP, self.tiltI, self.tiltD)

        self.panPID.initialize()
        self.tiltPID.initialize()

        rospy.logwarn("AprilTag Tracking Node [ONLINE]...")

        # rospy shutdown
        rospy.on_shutdown(self.cbShutdown)

        # Subscribe to CompressedImage msg
        self.cameraInfo_topic = "/cv_camera/camera_info_converted"
        self.cameraInfo_sub = rospy.Subscriber(self.cameraInfo_topic,
                                               CameraInfo, self.cbCameraInfo)

        # Subscribe to objCenter msg
        self.objCoord_topic = "/objCoord"
        self.objCoord_sub = rospy.Subscriber(self.objCoord_topic, objCoord,
                                             self.cbObjCoord)

        # Publish to Twist msg
        self.telloCmdVel_topic = "/cmd_vel"
        self.telloCmdVel_pub = rospy.Publisher(self.telloCmdVel_topic,
                                               Twist,
                                               queue_size=10)

        # Allow up to one second to connection
        rospy.sleep(1)

    # Convert image to OpenCV format
    def cbCameraInfo(self, msg):

        self.imgWidth = msg.width
        self.imgHeight = msg.height

    # Convert image to OpenCV format
    def cbObjCoord(self, msg):

        self.objectCoordX = msg.centerX
        self.objectCoordY = msg.centerY

    def cbAprilTag(self):

        self.cbPIDerr()

    # show information callback
    def cbPIDerr(self):

        self.panErr, self.panOut = self.cbPIDprocess(self.panPID,
                                                     self.objectCoordX,
                                                     self.imgWidth // 2)
        self.tiltErr, self.tiltOut = self.cbPIDprocess(self.tiltPID,
                                                       self.objectCoordY,
                                                       self.imgHeight // 2)

    def cbPIDprocess(self, pid, objCoord, centerCoord):

        # calculate the error
        error = centerCoord - objCoord

        # update the value
        output = pid.update(error)

        return error, output

    def cbCallErr(self):
        self.cbAprilTag()

        panSpeed = mapped(abs(self.panOut), 0, self.imgWidth // 2, 0,
                          self.MAX_ANG_VEL)
        tiltSpeed = mapped(abs(self.tiltOut), 0, self.imgHeight // 2, 0,
                           self.MAX_LIN_VEL)

        #		if self.panOut < 0:
        #			self.telloCmdVel.linear.x = panSpeed
        #		elif self.panOut > 0:
        #			self.telloCmdVel.linear.x = -panSpeed
        #		else:
        #			self.telloCmdVel.linear.x = 0

        if self.tiltOut > 0.04:
            self.telloCmdVel.angular.z = -panSpeed
        elif self.tiltOut < -0.04:
            self.telloCmdVel.angular.z = panSpeed
        else:
            self.telloCmdVel.angular.z = 0

        self.telloCmdVel.linear.x = 0.0
        self.telloCmdVel.linear.y = 0.0
        self.telloCmdVel.linear.z = 0.0

        self.telloCmdVel.angular.x = 0.0
        self.telloCmdVel.angular.y = 0.0

        self.telloCmdVel_pub.publish(self.telloCmdVel)

    # rospy shutdown callback
    def cbShutdown(self):

        rospy.logerr("AprilTag Tracking Node [OFFLINE]...")