def fingerControl(self, finger, motorDir):

        # TODO - TODO - While needs an output condition?
        logging.info("IOUTILS::fingerControl")
        """ With these three lines of code, the control of a single motor is achieved.
		First the feedback value of the controller is obtained from a specific channel
		of the ADC IC. Then, the control signal is computed with a PID. Finally, the
		control signal is applied to the motor as a PWM signal generated by the PWM IC.
		"""
        # Initialize PID
        pid = PID(PID_KP, PID_KI, PID_KD)

        pid.setWindup = MOTOR_CTRL_MAX
        pid.setSampleTime = 0.2
        pid.SetPoint = 800

        # Initialize buses
        # Re-init will be necessary?
        # self.adc = MCP3008.MCP3008(clk=CLK, cs=CS, miso=MISO, mosi=MOSI)

        # Initialize PWM
        # Re-init will be necessary?
        #self.pwm = PCA9685.PCA9685(PCA_I2C_ADDR)
        #self.pwm.set_pwm_freq(PWM_FRQUENCY)

        logging.debug("IOUTILS::fingerControl - Reading from ADC Channel [%i]",
                      FINGER_CHANNELS_MATRIX[ADC][finger])

        while True:
            feedback = self.getPotentiometerValue(finger)
            pid.update(feedback)
            duty_cycle = int(pid.output)
            self.motor_control(duty_cycle, finger, motorDir)
Example #2
0
def test_pid(P=0.2, I=0.0, D=0.0, L=100):
    """Self-test PID class

    .. note::
        ...
        for i in range(1, END):
            pid.update(feedback)
            output = pid.output
            if pid.SetPoint > 0:
                feedback += (output - (1/i))
            if i>9:
                pid.SetPoint = 1
            time.sleep(0.02)
        ---
    """
    pid = PID.PID(P, I, D)

    pid.SetPoint = 0.0
    pid.setSampleTime(0.01)

    END = L
    feedback = 0

    feedback_list = []
    time_list = []
    setpoint_list = []

    for i in range(1, END):
        pid.update(feedback)
        output = pid.output
        if pid.SetPoint > 0:
            feedback += (output - (1 / i))
        if i > 9:
            pid.SetPoint = 1
        time.sleep(0.02)

        feedback_list.append(feedback)
        setpoint_list.append(pid.SetPoint)
        time_list.append(i)

    time_sm = np.array(time_list)
    time_smooth = np.linspace(time_sm.min(), time_sm.max(), 300)
    feedback_smooth = spline(time_list, feedback_list, time_smooth)

    plt.plot(time_smooth, feedback_smooth)
    plt.plot(time_list, setpoint_list)
    plt.xlim((0, L))
    plt.ylim((min(feedback_list) - 0.5, max(feedback_list) + 0.5))
    plt.xlabel('time (s)')
    plt.ylabel('PID (PV)')
    plt.title('TEST PID')

    plt.ylim((1 - 0.5, 1 + 0.5))

    plt.grid(True)
    plt.show()
Example #3
0
def test_pid(P = 0.2,  I = 0.0, D= 0.0, L=100):
    """Self-test PID class

    .. note::
        ...
        for i in range(1, END):
            pid.update(feedback)
            output = pid.output
            if pid.SetPoint > 0:
                feedback += (output - (1/i))
            if i>9:
                pid.SetPoint = 1
            time.sleep(0.02)
        ---
    """
    pid = PID.PID(P, I, D)

    pid.SetPoint=0.0
    pid.setSampleTime(0.01)

    END = L
    feedback = 0

    feedback_list = []
    time_list = []
    setpoint_list = []

    for i in range(1, END):
        pid.update(feedback)
        output = pid.output
        if pid.SetPoint > 0:
            feedback += (output - (1/i))
        if i>9:
            pid.SetPoint = 1
        time.sleep(0.02)

        feedback_list.append(feedback)
        setpoint_list.append(pid.SetPoint)
        time_list.append(i)

    time_sm = np.array(time_list)
    time_smooth = np.linspace(time_sm.min(), time_sm.max(), 300)
    feedback_smooth = spline(time_list, feedback_list, time_smooth)

    plt.plot(time_smooth, feedback_smooth)
    plt.plot(time_list, setpoint_list)
    plt.xlim((0, L))
    plt.ylim((min(feedback_list)-0.5, max(feedback_list)+0.5))
    plt.xlabel('time (s)')
    plt.ylabel('PID (PV)')
    plt.title('TEST PID')

    plt.ylim((1-0.5, 1+0.5))

    plt.grid(True)
    plt.show()
Example #4
0
def run_controllers(main_d):
    while main_d["running"]:
        for i in range(0, 4):
            # main_d["pid"][i]["current"] = loadcell.get_value(i)

            pid.update(main_d["pid"][i])

            # arduino.set_pwm(main_d["arduino"], i, main_d["pid"][i]["output"])

        # gfx.log(main_d["pid"][0]["current"])

        time.sleep(pid.DELTA_TIME)
Example #5
0
def Pid_Adjast(move_speed, isforward):
    angle = motion.getGyro()
    pid.update(angle)
    out = int(abs(pid.output * 10))

    print "angle:" + str(angle)
    print "out:" + str(out)

    if angle >= 5:
        motion.motion_wheelspeed(-move_speed, -move_speed - out)
    elif angle <= -5:
        motion.motion_wheelspeed(-move_speed - out, -move_speed)
    else:
        pass
Example #6
0
import os, time
import pid
import sys
import Motion
# os.system('espeak -s 120 -v zh \'woyaoshiyong\' --stdout|aplay')
# os.system('espeak -s 120 -v en-us \'p i d\' --stdout|aplay')
# os.system('espeak -s 120 -v zh \'suanfa\' --stdout|aplay')

# pid= pid.PID(P=sys.argv[1],I=sys.argv[2],D=sys.argv[3])
pid = pid.PID(P=0.2, I=0.2, D=0.3)
motion = Motion.motion()

while True:
    # time.sleep(1)
    angle = motion.getGyro()
    pid.update(angle)
    out = int(pid.output * 10)
    print "\n"
    print angle
    print out
    print motion.getDist()

    if out >= 1000:
        out = 1000
    elif out <= -1000:
        out = -1000

    if angle >= 0:
        motion.motion_left(-out)
    else:
        motion.motion_right(out)
Example #7
0
    def main(self, raw_cap, gr_cap):

        # Update loop count
        # print(self.num_CW_detected)
        # # print(self.crossing_count)
        # print(self.no_ped_count)
        print("----------------")
        print("crosswalk stuff:")
        print("crosswalk: " + str(self.detected_crosswalk))
        print("pedestrian: " + str(self.detected_pedestrian))
        print("no ped count:" + str(self.no_ped_count))
        print("seen redline this many times: " + str(self.entering_cw))
        print("has it passed crosswalk yet: " + str(self.passedCW))
        print("has it seen corner yet: " + str(self.detected_corner))
        print("has it found plate yet: " + str(self.foundPlate))
        print("has it seen last corner yet:" + str(self.lastCorner))
        print("this is 3rd corner count:" + str(self.thirdCorCount))
        print("----------------")
        print("plate stuff:")
        print("this is count_detect_mode:" + str(self.count_detect_mode))
        # print("this is count_loop_save:" + str(self.count_loop_save))
        # print("has not successfully got a plate for:" + str(self.noPlateCount))
        print("has it stopped to read plate yet?" + str(self.stopForPlate))
        print("has image been saved yet?" + str(self.savedImage))
        print("this many images have been saved:" +
              str(my_plate_locator.numSavedImages))
        # print("is it getting back out:" + str(self.getBackOut))

        if my_plate_locator.numSavedImages == 5:  # can be changed to 5
            self.allDone = True
            self.doneEarly = True
            self.time_elapsed = rospy.get_time() - self.time_start

        if my_plate_locator.numSavedImages == 4 and not self.secondCW:
            self.passedCW = False
            self.secondCW = True
            self.foundPlate = False
            self.stopRushing = False

        if self.secondCW:
            if not self.foundPlate and detection.path.corner(gr_cap):
                self.countCWCorner += 1
                if self.countCWCorner > 5:
                    print("found corner!!! now sweeping!!!")
                    self.move.linear.x = 0
                    self.move.angular.z = -1.8 * constants.CONST_ANG
                    self.detected_corner = True

        if my_plate_locator.numSavedImages == 2:
            if not self.firstCor:
                if not self.foundPlate and detection.path.corner(gr_cap):
                    print("found corner!!! now sweeping!!!")
                    self.move.linear.x = 0
                    self.move.angular.z = -0.5 * constants.CONST_ANG
                    self.detected_corner = True

            if self.firstCor and not self.passedCW:
                self.foundPlate = False

        if my_plate_locator.numSavedImages == 4 and self.passedCW:
            if not self.thirdCor:
                self.thirdCorCount += 1
                self.move.linear.x *= RUSHING_FACTOR
                if self.thirdCorCount > LAST_CORNER_COUNT_LIM and self.thirdCorCount < LAST_CORNER_COUNT_LIM + 15 and not self.lastCorner:
                    print("found corner!!! now sweeping!!!")
                    self.move.linear.x = 0
                    self.move.angular.z = -2.5 * constants.CONST_ANG

                if self.thirdCorCount >= LAST_CORNER_COUNT_LIM + 15:
                    self.lastCorner = True

        # !!!!!!! ONLY do these when not in the process of stopping and reading plate.
        # Get crosswalk
        # Only start crosswalk detection after at least 2 plates have been saved
        if not self.stopForPlate:

            if my_plate_locator.numSavedImages > 1 and not self.passedCW:
                if not self.secondCW:
                    self.crosswalkFunc(raw_cap)

                else:
                    if self.foundPlate:
                        self.crosswalkFunc(raw_cap)
                # else:
                #     self.detected_crosswalk = [False, False]

            # Get path state
            if self.entering_cw == 0 and not self.passedCW and not self.secondCW:
                state = detection.path.state(gr_cap, self.detected_crosswalk)

            else:
                print("manually change to False False")
                state = detection.path.state(gr_cap, [False, False])

            print(state)

            if self.passedCW:
                print(self.passedCW_count)
                self.passedCW_count += 1
                if self.passedCW_count > 50 and detection.path.corner(
                        gr_cap) and not self.foundPlate:
                    self.detected_corner = True
                    self.stopRushing = True

                if self.detected_corner:
                    print("found corner! now sweeping!!!")
                    self.move.linear.x = 0
                    self.move.angular.z = -2.5 * constants.CONST_ANG

            if self.detected_corner and state == [0, 1]:
                if my_plate_locator.numSavedImages == 2 and self.passedCW:
                    print("found plate! stop sweeping")
                    self.foundPlate = True
                    self.detected_corner = False
                    self.stopForPlate = True
                    self.count_detect_mode = COUNT_DETECT_MODE_LIM + 1
                    self.move.linear.x = 0
                    self.move.angular.z = 0

            if self.detected_corner and state == [0, 1]:
                if my_plate_locator.numSavedImages == 4:
                    print("found plate! stop sweeping")
                    self.foundPlate = True
                    self.detected_corner = False
                    self.move.linear.x = 0
                    self.move.angular.z = 0
                    if self.passedCW:
                        self.lastCorner = True

            if not self.firstCor and self.detected_corner and state == [
                    2, -1
            ] and my_plate_locator.numSavedImages == 2:
                print("found plate! stop sweeping")
                self.foundPlate = True
                self.detected_corner = False
                self.firstCor = True
                self.move.linear.x = 0
                self.move.angular.z = 0

            if self.firstCor and my_plate_locator.numSavedImages == 4 and not self.thirdCor and self.detected_corner and state == [
                    2, -1
            ]:
                print("found plate! stop sweeping")
                self.foundPlate = True
                self.detected_corner = False
                self.thirdCor = True
                self.thirdCorCount = 0
                self.move.linear.x = 0
                self.move.angular.z = 0

            # getting back out of the bad orientation
            if self.getBackOut_count == 0 and self.foundPlate and my_plate_locator.numSavedImages > 2:
                self.move.linear.x = 0
                self.getBackOut = True
                self.move.angular.z = 0 * constants.CONST_ANG
                print("getting back out!")
        # if state == [0, 1]:
        #     self.canSweepNow = False
        #     print("Stop sweeping now")

        # Get/set velocities only when crosswalk is not present
        if not self.getBackOut and not self.stopForPlate and self.entering_cw < CROSSING_COUNT_LIM + 2 and not self.detected_pedestrian and not self.detected_corner:
            if self.thirdCorCount <= LAST_CORNER_COUNT_LIM or self.thirdCorCount >= LAST_CORNER_COUNT_LIM + 15:
                print("updating pid")
                pid.update(self.move, state)

        if self.getBackOut and self.getBackOut_count > 6:
            print("finishing getting back out now")
            self.getBackOut = False
            self.move.angular.z = 0

        if self.getBackOut:
            self.getBackOut_count += 1

        # Rush out of crosswalk
        if my_plate_locator.numSavedImages != 4 and self.passedCW and not self.stopRushing:
            self.move.linear.x *= RUSHING_FACTOR

            # self.move.angular /= RUSHING_FACTOR
        # Publish the state anytime
        self.pub.publish(self.move)

        #------------------------------------------------------------------------------------------------------------------------------------

        if my_plate_locator.numSavedImages == 2 and self.foundPlate:
            print("do not move until 3rd plate is found")
            self.count_detect_mode = COUNT_DETECT_MODE_LIM + 1
            # self.move.angular.z = -9 * pid.CONST_ANG
            # self.pub.publish(self.move)

        # only check for plate if wanted:
        if (my_plate_locator.numSavedImages == 2 and not self.passedCW):
            used_count_detect_mode_lim = CORRECTED_COUNT_DETECT_MODE_LIM
            used_loop_count_lim = CORRECTED_LOOP_COUNT_LIM
        elif (my_plate_locator.numSavedImages == 2
              and self.foundPlate) or not self.passedCW:
            used_count_detect_mode_lim = COUNT_DETECT_MODE_LIM
            used_loop_count_lim = LOOP_COUNT_LIM
        elif my_plate_locator.numSavedImages == 3:
            used_count_detect_mode_lim = LESS_COUNT_DETECT_MODE_LIM
            used_loop_count_lim = LESS_LOOP_COUNT_LIM
        else:
            used_count_detect_mode_lim = LAST_COUNT_DETECT_MODE_LIM
            used_loop_count_lim = LAST_LOOP_COUNT_LIM

        if (not self.passedCW
                and not self.detected_pedestrian) or (self.passedCW
                                                      and self.foundPlate):

            if self.thirdCorCount > LAST_PLATE_COUNT_LIM or (
                    not self.savedImage
                    and self.count_detect_mode > used_count_detect_mode_lim):
                print("checking for plates")
                if self.noPlateCount < NO_PLATE_MOVE_ON_LIM or self.foundPlate:

                    self.stopForPlate = True

                    # make it stop IMMEDIATELY, it will be too late if wait until method finishes
                    self.move.linear.x = 0
                    self.move.angular.z = 0
                    self.pub.publish(self.move)

                    self.count_detect_mode = 0

                    try:
                        print("entered try block!")

                        if my_plate_locator.locate_plate(
                                gr_cap, self.count_loop_save):
                            self.savedImage = True
                            self.stopForPlate = False  # Resume
                            self.count_loop_save = 0
                            self.count_loop = 0

                        else:
                            self.count_loop_save += 1
                            self.count_detect_mode = used_count_detect_mode_lim + 1

                        if self.count_loop_save > 1:
                            self.noPlateCount += 1
                            self.loopcount += 1

                    except (ValueError, UnboundLocalError, IndexError,
                            AttributeError):
                        print("error caught")
                        self.noPlateCount += 1
                        self.loopcount += 1

                else:
                    print("could not find plate, move on")
                    self.stopForPlate = False
                    self.noPlateCount = 0
                    self.loopcount = 0
                    self.count_loop_save = 0
                    self.count_detect_mode = 0

            else:
                print("not checking for plates")
                self.stopForPlate = False
                self.loopcount += 1
                self.count_detect_mode += 1

                if self.loopcount > used_loop_count_lim:
                    self.savedImage = False
                    self.loopcount = 0

        cv2.imshow("robot cap", gr_cap)
        cv2.waitKey(1)