带编码器和PID raspberryPi的行跟随

时间:2018-07-04 12:44:41

标签: raspberry-pi sensor pid encoder

嗨,我和一个朋友一直在研究机器人,希望获得帮助。目前,我们正在使用一个库来运行电动机。以下是红外传感器,电机和其他一些东西的库:

from mirto_asip_manager.asip_manager import AsipManager
from time import sleep
from mirto_asip_manager.settings import logging as log
import time

class MirtoRobot:
    def __init__(self, debug: bool, services_on: dict) -> None:
    self.robot = AsipManager(debug)
    self.robot.initialize_main(services_on)
    self.get_version_info()

def terminate(self) -> None:
    """
    Function which is making all threads and ports terminated
    :return:
    """
    self.robot.terminate_all()

def get_version_info(self):
    """
    Getting and displaying information about current system installed on mirto robot
    :return:
    """
    sys_info_service = self.robot.all_services.get("sys_info")
    if sys_info_service is not None:
        log.info("System version info: %s" % sys_info_service.system_version)
    else:
        log.warning("Service get_version_info is not enabled!")

def get_left_encoder_values(self, delta: bool=False) -> list:
    """
    Retrieving left wheel encoder values. Please provide True or False if delta values required
    :param delta:
    :return:
    """
    encoders = self.robot.all_services.get('encoders')
    if encoders is not None:
        left_values_all = encoders.left_values
        if delta:
            return left_values_all
        else:
            return left_values_all[1]
    else:
        log.warning("Service encoders is not enabled!")

def get_right_encoder_values(self, delta: bool=False) -> list:
    """
    Retrieving right wheel encoder values. Please provide True or False if delta values required
    :param delta:
    :return:
    """
    encoders = self.robot.all_services.get('encoders')
    if encoders is not None:
        right_values_all = encoders.right_values
        if delta:
            return right_values_all
        else:
            return right_values_all[1]
    else:
        log.warning("Service encoders is not enabled!")

def get_encoders_values(self, delta: bool=False) -> list:
    """
    Function getting encoders count for both wheels. Please provide True if delta value is required.
    :return: Encoders counts
    :rtype: list
    """
    encoders = self.robot.all_services.get('encoders')
    if encoders is not None:
        values_all = encoders.all_values
        if delta:
            return values_all
        else:
            return [values_all[0][1], values_all[1][1]]
    else:
        log.warning("Service encoders is not enabled!")

def set_motors(self, speed0: int, speed1: int) -> None:
    """
    Input is a speed value which is send to robot. Range: -100 -> 100
    :param speed0:
    :param speed1:
    :return:
    """
    motor_1 = self.robot.all_services.get('motor_1')
    motor_2 = self.robot.all_services.get('motor_2')
    if motor_1 or motor_1 is not None:
        motor_1.set_motor(speed0)
        motor_2.set_motor(speed1)
        log.info("Setting motor: '{}': {} motor:'{}': {}".format(motor_1.name, speed0, motor_2.name, speed1))
    else:
        log.warning("One of the motors is not enabled!")

def stop_motors(self) -> None:
    """
    Sending speed value 0 to both motor will cause robot to stop
    :return:
    """
    motor_1 = self.robot.all_services.get('motor_1')
    motor_2 = self.robot.all_services.get('motor_2')
    if motor_1 is not None or motor_1 is not None:
        motor_1.stop_motor()
        motor_2.stop_motor()
        log.info("Motors stopped")
    else:
        log.warning("One of the motors is not enabled!")

def get_ir_sensors_values(self) -> list:
    """
    Receiving ir sensors values, then appending to the list and returning. Please amend the order list if sensors
    are positioned in different order.
    :return:
    """
    ir_sensors = self.robot.all_services.get('ir_sensors')
    if ir_sensors is not None:
        ir_sensors_order = [0, 1, 2]
        ir_all_values = []
        for num in ir_sensors_order:
            ir_all_values.append(ir_sensors.ir_all_values[num])
        return ir_all_values
    else:
        log.warning("Service IR sensors is not enabled!")

def play_tone(self, frequency, duration):
    """
    This function allows to play sound with specific frequency for give duration.
    :return: None
    """
    tone = self.robot.all_services.get("tone")
    if tone is not None:
        tone.play_tone(frequency, duration)
        log.info("Finish playing tone")
    else:
        log.warning("Service tone is not enabled!")

def test_play_tone(self):
    self.play_tone(440, 2000)
    sleep(1)
    log.info("Finished test for tone service")

def test_encoders(self, interval: float=0.1, time_to_finish: int=10) -> None:
    end_time = time.time() + time_to_finish
    while time.time() < end_time:
        print(self.get_left_encoder_values(True), self.get_right_encoder_values(True))
        sleep(interval)
    log.info("Finish encoder test")

def test_motor(self, with_encoders: bool=False, period: time=5) -> None:
    self.set_motors(30, 30)
    if with_encoders:
        self.test_encoders(0.1, period)
    else:
        sleep(period)
    self.stop_motors()

def test_ir_sensors(self, time_to_finish: int = 10, interval: float = 0.1) -> None:
    end_time = time.time() + time_to_finish
    while time.time() < end_time:
        print(self.get_ir_sensors_values())
        sleep(interval)


if __name__ == '__main__':
services_to_run = {"encoders": [True, False], "motors": [True, False], "ir_sensors": [True, False]}
# Run services test
mirto = MirtoRobot(debug=False, services_on=services_to_run)
mirto.test_encoders(0.1, 2)
mirto.test_motor(True, 2)
mirto.test_ir_sensors(2, 0.2)
# This will stop all threads and close ports
mirto.terminate()

我想知道是否有人可以帮助我提出一个完成的代码,该代码使用编码器和PID进行行跟随。在下面的代码行中,我有我的代码,但未使用PID或编码器:

     # importing library
    from time import sleep
    from asip.serial_mirto_robot import SerialMirtoRobot
    robot = SerialMirtoRobot()

    # creating a function call read_all_ir_values that reads the values from     the ir sensors on the mirto robot
def read_all_ir_values():
    """
    This function is reading values for all ir sensors.`enter code here`

    example
    # :param i:
    # :type i: int
    end of example
    :return: IR Sensor values
    :rtype: array
    """
    # variable called values that will hold an array
    values = []

    # range stands for all sensors.
    # 0 is left, 2 is center and 1 is right
    ir_order = [0, 2, 1]

    # for loop
    for i in ir_order:
        # takes each reading and then adds each reading for example ir 0 = 345, ir 2 = 532, ir 1 = 684 into array called value which will give you [345, 532, 684]
        values.append(robot.get_ir(i))
    # returns the array with each ir value
    return values

# creating a function call read_all_ir_values that retreive the values from each individual ir sensor. similar to the top one but returns true if ir on black surface
def getSensorReadings():
    """
        This function is reading values for all ir sensors.
        example
        # :param i:
        # :type i: int
        end of example
        :return: IR Sensor values
        :rtype: array
        """
    # variable called values that will hold an array
    values = []

    # 0 is left, 1 is center and 2 is right

    ir_order = [0, 2, 1]

    # so this will give you an array of True (if on black) False (if on White) and 0 (if nothing)
    for i in ir_order:

        tempValue = robot.get_ir(i)
        # variable called threshold which is equalled to 500. this is the value that we compare each ir value to e.g. if ir value > 500 then do this....
        threshold = 300
        # we take the ir reading and say if it is greater than our threshold which is 500
        if tempValue > threshold:
            # if ir value is greater than the threshold add True to that ir number in the array e.g. if the ir 0 value is higher than 500, it will put true it the array like [True, ir 2, 1]]
            values.append(True)
        else:
            # if the ir value is not greater than 500, add False to that ir position in the array e.g. [ir 0, False, ir 1]
            values.append(False)
    # returns the complete array
    return values

# define function called forward. movies robot forward
def forward():
    robot.set_motors(85, 96)

# define function called backwards. movies robot backwards
def backwards():
    robot.set_motors(-85, -96)

# define function called left. movies robot left
def left():
    robot.set_motors(98, 20)

# define function called right. movies robot right
def right():
    robot.set_motors(20, 99)

# define function called brake. movies robot brake
def brake():
    robot.stop_motors()

# try is used for error handeling. for example we say try: this loop, if the loop is true, then continue to execute that loopself however
# if at a certain point in the loop, a false result is evaluated from a line of code then print "error". the "error" print is shown at the bottom.
try:

    # a while loop
    while True:
        all_values = getSensorReadings()

        left_sensor = all_values[0]
        center_sensor = all_values[1]
        right_sensor = all_values[2]

        values = read_all_ir_values()

        print (all_values)


        print("Values from IR: %s" % values)

        if left_sensor:
             left()
        elif right_sensor:
             right()
        else:
             forward()


        # print arrays every 0.2 seconds the quicker it prints, the more precise the ir values are
        sleep(0.01)


except Exception as error:
    print (error)

0 个答案:

没有答案