def __init__(self): self.scan_y = 60 # num pixels from the top to start horiz scan self.scan_height = 10 # num pixels high to grab from horiz scan self.color_thr_low = np.asarray((0, 50, 50)) # hsv dark yellow self.color_thr_hi = np.asarray((50, 255, 255)) # hsv light yellow self.target_pixel = None # of the N slots above, which is the ideal relationship target self.steering = 0.0 # from -1 to 1 self.throttle = 0.15 # from -1 to 1 self.recording = False # Set to true if desired to save camera frames self.delta_th = 0.1 # how much to change throttle when off self.throttle_max = 0.3 self.throttle_min = 0.15 # These three PID constants are crucial to the way the car drives. If you are tuning them # start by setting the others zero and focus on first Kp, then Kd, and then Ki. self.pid_st = PID(Kp=-0.01, Ki=0.00, Kd=-0.001)
def __init__(self): self.pid = PID(0.4, 0.8, 0.02, setpoint=0, sample_time=0.01) #self.pid = PID(0.32, 0.8, 0.02, setpoint=0, sample_time=0.01) self.pid.output_limits = (-1.0,1.0) self.pid.proportional_on_measurement = True # Set the target position print("PID: ", self.pid.tunings) # Current forward speed of motors self.current_speed = 0.0 # points to plot self.setpoint = [] self.speed = [] self.PIDctrls = [] self.PIDerror = []
def __init__(self, config: PluginConfig, client: mclient.Client, log: logging.Logger): self._hvac = None self._config = config self._mqtt = client self._shedule_task = None self._last_output = 0 self._pid = PID( Kp=self._config.get("Kp", 1.0), Ki=self._config.get("Ki", 0.0), Kd=self._config.get("Kd", 0.0), setpoint=self._config.get("target", 20), sample_time=self._config.get("pid_frequenzy", 0.1), output_limits=(0, 255) ) self._valve = Valve(log, config) self._logger = log
def AutoLand(): #ultrasonic.distance() returns distance in cm. 11cm is height from ground. 12 should be good then to drop LandPID = PID(-0.5, 0.1, 0.05, setpoint=12) LandPID.sample_time = 0.01 pid.output_limits = (300, 325) # output value will be between 0 and 10 #Current distance away distance = ultrasonic.distance() while distance > 12: control = LandPID(distance) #Change throttle - control needs to be between 240-420 talktopi(ZERO_VALUE, ZERO_VALUE, control, ZERO_VALUE) #update distance distance = ultrasonic.distance() #Turn off motors talktopi(ZERO_VALUE, ZERO_VALUE, MIN_VALUE, ZERO_VALUE) time.sleep(1)
def test_reset_I_term(): pid = PID(0, 10, 0, setpoint=-10, sample_time=0.1) time.sleep(0.1) assert round(pid(0)) == -10.0 time.sleep(0.1) assert round(pid(0)) == -20.0 time.sleep(0.1) pid.reset_integral_term_to = 0 assert round(pid(0)) == 0 time.sleep(0.1) pid.reset_integral_term_to = None assert round(pid(0)) == -10.0
def __init__(self, adc: DummyADC, sabertooth, port_id, constants=(5, 0.01, 0.1)): self.pos = adc.get_value() self.adc = adc self.st = sabertooth self.id = port_id self.estop = False kp, ki, kd = constants self.pid = PID(kp, ki, kd, setpoint=self.adc.get_value(), sample_time=0.02, output_limits=(-1, 1)) self.bal_thread = threading.Thread(target=self._balance, args=()) self.bal_thread.daemon = True self.bal_thread.start()
def __init__(self, model_class, move_done_signals=[], grab_done_signals=[], move_modules_commands=[], detector_modules_commands=[], params=dict([]), filter=dict([]), det_averaging=[] ): """ Init the PID instance with params as initial conditions Parameters ---------- params: (dict) Kp=1.0, Ki=0.0, Kd=0.0,setpoint=0, sample_time=0.01, output_limits=(None, None), auto_mode=True, proportional_on_measurement=False) """ super().__init__() self.model_class = model_class self.move_done_signals = move_done_signals self.grab_done_signals = grab_done_signals self.det_averaging = det_averaging self.move_modules_commands = move_modules_commands self.detector_modules_commands = detector_modules_commands self.current_time = 0 self.input = 0 self.output = None self.output_to_actuator = None self.output_limits = None, None self.filter = filter # filter=dict(enable=self.settings.child('main_settings', 'filter', # 'filter_enable').value(), value=self.settings.child('main_settings', 'filter', 'filter_step').value()) self.pid = PID(**params) # #PID(object): self.pid.set_auto_mode(False) self.refreshing_ouput_time = 200 self.running = True self.timer = self.startTimer(self.refreshing_ouput_time) self.det_done_datas = OrderedDict() self.move_done_positions = OrderedDict() self.move_done_flag = False self.det_done_flag = False self.paused = True self.timeout_timer = QtCore.QTimer() self.timeout_timer.setInterval(10000) self.timeout_scan_flag = False self.timeout_timer.timeout.connect(self.timeout)
def __init__(self, kp, ki, kd, *args, sample_time=None, proportional_on_measurement=False, **kwargs): super().__init__(*args, **kwargs) self.pid = PID(Kp=kp, Ki=ki, Kd=kd, setpoint=self.setpoint, sample_time=sample_time, output_limits=(self.min_output, self.max_output), auto_mode=True, proportional_on_measurement=proportional_on_measurement)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.enabled = False self.heading = None self.target_heading = None self.current_location = None self.target_waypoint = None self.update_frequency = 10 self.arrived = False self.waypoints = deque() self.completed_waypoints = [] # the pid setpoint is the error setpoint # and thus we always want the error to be 0 regardless of the scale # we use to feed into the pid. self.pid = PID(config.kP, config.kI, config.kD, setpoint=0, output_limits=(-100, 100)) self.pid_output = None self.heading_error = None
def __init__(self, timer_tick): sample_time = timer_tick / 1000. self.Kp = 20 self.Ki = 5 self.Kd = -0.2 self.left_setpoint = 0 self.pid = PID(Kp=self.Kp, Ki=self.Ki, Kd=self.Kd, setpoint=self.left_setpoint, sample_time=sample_time, output_limits=(-MAX_SPEED, MAX_SPEED)) self.mpu = mpu() self.motors = motors
def populate_vessels(): for vessel_id in set([ x.split("/")[1] for x in config.sections() if x.startswith("vessels/") ]): name = config.get("vessels/" + vessel_id, "name", fallback="Unknown name") pid = PID(float(config.get("vessels/" + vessel_id + "/pid", "p")), float(config.get("vessels/" + vessel_id + "/pid", "i")), float(config.get("vessels/" + vessel_id + "/pid", "d")), setpoint=1, output_limits=(0, 100)) # Monkey-patch last seen output value into PID objects. This is for convenience # since the PID objects are used by both Sensor and Heater. pid.output = 0 sensor_id = config.get("vessels/" + vessel_id, "sensor_id", fallback="") temp_offset = float( config.get("vessels/" + vessel_id + "/sensor/" + sensor_id, "temp_offset", fallback=0.0)) gpio_pin = config.get("vessels/" + vessel_id + "/heater", "gpio_pin") sensor = Sensor(name=name, id_=vessel_id, scheduler=apsched, sensor_id=sensor_id, temp_offset=temp_offset, pid=pid, notify_change=notify_change) heater = Heater(gpio_pin, name, id_=vessel_id, sensor=sensor, pid=pid, scheduler=apsched, notify_change=notify_change) vessel = Vessel(vessel_id, name, heater=heater, sensor=sensor, pid=pid) state["vessels"][vessel_id] = vessel
def get_in_position_to_grab_pipe(self): # get close to the pipe with PID pid = PID(54, 0, 25, setpoint=0) default = 200 max_speed_bound = 500 max_control = max_speed_bound - default min_control = -max_speed_bound + default # baseado no cano o max approach tera que mudar --- no cano de 20 1 é ideal max_approach_k = 4 first_key = False second_key = False k_to_identify_perpendicular = 5 while True: lis = self.get_sensor_data("InfraredSensor") left = lis[0] right = lis[1] upper_front = lis[2] print(lis) if left <= max_approach_k or right <= max_approach_k or upper_front <= max_approach_k: first_key = True if abs(left - right) > k_to_identify_perpendicular and upper_front < 15: print("its perpendicular") break if first_key and abs(left - right) <= 1 and min(left, right) < 5: second_key = True if first_key and second_key: print("its parallel") break control = pid(left - right) if control > max_control: control = max_speed_bound - default elif control < min_control: control = -max_speed_bound + default self.motors.left.run_forever(speed_sp=default - control) self.motors.right.run_forever(speed_sp=default + control) self.stop_motors()
def __init__(self, tf_session, should_jitter_actions=True, net_path=None, use_frozen_net=False, path_follower=False, output_last_hidden=False, net_name=c.ALEXNET_NAME, driving_style: DrivingStyle = DrivingStyle.NORMAL): np.random.seed(c.RNG_SEED) self.previous_action = None self.previous_net_out = None self.step = 0 self.net_name = net_name self.driving_style = driving_style # State for toggling random actions self.should_jitter_actions = should_jitter_actions self.episode_action_count = 0 self.path_follower_mode = path_follower self.output_last_hidden = output_last_hidden if should_jitter_actions: log.info('Mixing in random actions to increase data diversity ' '(these are not recorded).') # Net self.sess = tf_session self.use_frozen_net = use_frozen_net if net_path is not None: if net_name == c.ALEXNET_NAME: input_shape = c.ALEXNET_IMAGE_SHAPE elif net_name == c.MOBILENET_V2_NAME: input_shape = c.MOBILENET_V2_IMAGE_SHAPE else: raise NotImplementedError(net_name + ' not recognized') self.load_net(net_path, use_frozen_net, input_shape) else: self.net = None self.sess = None self.throttle_pid = PID(0.3, 0.05, 0.4) self.throttle_pid.output_limits = (-1, 1) self.jitterer = ActionJitterer()
def track_to_target(self, target_northing: float, target_easting: float, target_alt: float) -> bool: """ Maintains a track from the point the simulation started at to the target point ... This ensures the aircraft does not fly a curved homing path if displaced from track but instead aims to re-establish the track to the pre-defined target point in space. The method terminates when the aircraft arrives at a point within 200m of the target point. :param target_northing: latitude of target relative to current position [m] :param target_easting: longitude of target relative to current position [m] :param target_alt: demanded altitude for this path segment [feet] :return: flag==True if the simulation has reached the target """ if self.nav is None: # initialize target and track self.nav = LocalNavigation(self.sim) self.nav.set_local_target(target_northing, target_easting) self.track_bearing = self.nav.bearing() * 180.0 / math.pi if self.track_bearing < 0: self.track_bearing = self.track_bearing + 360.0 self.track_distance = self.nav.distance() self.flag = False if self.nav is not None: # position relative to target bearing = self.nav.bearing() * 180.0 / math.pi if bearing < 0: bearing = bearing + 360 distance = self.nav.distance() off_tk_angle = self.track_bearing - bearing distance_to_go = self.nav.distance_to_go(distance, off_tk_angle) # use a P controller to regulate the closure rate relative to the track error = off_tk_angle * distance_to_go kp = 0.01 ki = 0.0 kd = 0.0 closure_controller = PID(kp, ki, kd) heading = closure_controller(-error) + bearing if distance < 200: self.flag = True self.nav = None return self.flag self.heading_hold(heading) self.altitude_hold(target_alt)
def __init__(self, id: int, i2c_lock: threading.Lock = None, one_wire_lock: threading.Lock = None, target_temperature: float = 25.0, enabled: bool = False, verbose: bool = True): self.id = id self.water_pump = WaterPump(id=id, i2c_lock=i2c_lock) self.pc_fan = PCFan(id=id, i2c_lock=i2c_lock) self.temperature_sensor = WaterTemperatureSensor( id=id, one_wire_lock=one_wire_lock) self.output = ESC(id=self._DEVICE_ID_MAP[id], i2c_lock=i2c_lock) self.target_setpoint = target_temperature self.Kp = 80.0 self.Ki = 0.2 self.Kd = 10.0 self.reset = 10 # instantiate PID controller self.pid = PID( Kp=self.Kp, Ki=self.Ki, Kd=self.Kd, setpoint=target_temperature, sample_time=1.0, # 1.0 s output_limits=(-100, 100), auto_mode=True, proportional_on_measurement=False) # initialize log arrays self.temp_log = list() self.kp_log = list() self.ki_log = list() self.kd_log = list() self.control_val_log = list() self.actual_temperature = -100 self.control_value = 0 self.enabled = enabled if not self.enabled: self.output.stop() self.verbose = verbose timestamp = time.strftime("%Y-%m-%d_%H:%M:%S") self.file = "log/{}_temperature_reactor{}.csv".format( timestamp, self.id)
def __init__(self): self.vert_scan_y = 60 # num pixels from the top to start horiz scan self.vert_scan_height = 50 # num pixels high to grab from horiz scan # self.color_thr_low = np.asarray((15, 0, 160)) # hsv dark yellow # self.color_thr_hi = np.asarray((50, 160, 255)) # hsv light yellow self.color_thr_low = np.asarray( (24, 55, 50)) # hsv dark yellow TENNIS BALL self.color_thr_hi = np.asarray( (85, 255, 255)) # hsv light yellow TENNIS BALL self.target_pixel = None # of the N slots above, which is the ideal relationship target self.steering = 0.0 # from -1 to 1 self.throttle = 0.15 # from -1 to 1 self.recording = False # Set to true if desired to save camera frames self.delta_th = 0.1 # how much to change throttle when off self.throttle_max = 0.3 self.throttle_min = 0.15 self.pid_st = PID(Kp=.03, Ki=0.0001, Kd=0.0025) self.cur_image = 0
def test_control(): pid = PID(2, 1, 1, setpoint=10) PV = 0 def update_system(C, dt): return PV + C * dt - 1 * dt start_time = time.time() last_time = start_time while time.time() - start_time < 10: C = pid(PV) PV = update_system(C, time.time() - last_time) last_time = time.time() # check if system has converged assert abs(PV - 10) < 0.1
def PID_Controller(self, rects, name): pid = PID(0.2, 0.5, 1, setpoint=2) if True: for (x, y, w, h) in rects: # Value of the central x in the bounding box pan = x + w / 2 # Pixels per one degree dg = 500 / 180 panLeft = (pan / dg) - 90 panRight = (pan - 250) // dg tmp = 0 if name != "Unknown": if pan > 250: outp = pid(panRight // 1) pantilthat.pan(outp) elif pan <= 250: outp = pid(panLeft // 1) pantilthat.pan(outp)
def __init__(self, simEng): self.sim = simEng self.gui = self.sim.gui self.th = TimeHelper() self.actionHistory = [0] self.plt = None #self.Kp = 0.023 self.pidValues = Widget() self.pidP = 0.023 self.pidI = 0.009 self.pidD = 0.0018 self.p = PID(self.pidP, self.pidI, self.pidD) #, setpoint=0,auto_mode=True ) self.p.proportional_on_measurement = True self.resp = 0.0002
def turn(self, degrees): startAngle = self.gyro.getMedianYaw(0.3) print('startAngle ' + str(startAngle)) endPoint = ((degrees+startAngle+180+360)%360)-180 print('endPoint ' + str(endPoint)); p = PID(1,0,0,setpoint=endPoint) curAngle = startAngle while abs(curAngle - endPoint) > 1: control = p(curAngle) print('control ' + str(control)) d = ((control + 360 + 180) % 360) - 180 print('d ' + str(d)) if d>0: self.motor.turnRightPWM(max(20,min(math.floor(d*4),100)),0.1) else: self.motor.turnLeftPWM(max(20,min(math.floor(-d*4),100)),0.1) curAngle = self.gyro.getMedianYaw(0.3) print('curAngle ' + str(curAngle))
def test_D_negative_setpoint(): pid = PID(0, 0, 0.1, setpoint=-10, sample_time=0.1) time.sleep(0.1) # should not compute derivative when there is no previous input (don't assume 0 as first input) assert pid(0) == 0 time.sleep(0.1) # derivative is 0 when input is the same assert pid(0) == 0 assert pid(0) == 0 time.sleep(0.1) assert round(pid(5)) == -5 time.sleep(0.1) assert round(pid(-5)) == 10 time.sleep(0.1) assert round(pid(-15)) == 10
def control_init(self): self._enabled = False self.pid = PID(1, 0.1, 0.05, setpoint=1) self.pid.output_limits = (0, 1) self.pid.sample_time = 2.0 self.sensor = W1ThermSensor() GPIO.setmode(GPIO.BCM) self._setpoint = 55 self._last_log_time = 0 self._log_interval = 5 # log every n seconds self._broadcast_interval = 5 self._last_broadcast_time = 0 self._actual_temperature = 0 self._v = 0 self._duty_cycle = 0 self.get_temperature() self.fan = OutputWrapper(13) self.heat = OutputWrapper(12)
def calibrate_exposure(ce_num_frames, ce_num_layers, ce_setpoint, exp_limit): global new_exp pid = PID(1.3, 0, 0, setpoint=ce_setpoint, sample_time=None) ce_layer_counter = 0 start_exposure = 80 new_exp = start_exposure cam.set_exposure(start_exposure) for i in range(ce_num_frames): if (ce_layer_counter < ce_num_layers): #if (i > 10): """if (laser_off(200,5)==1): ce_layer_counter+=1 print(ce_layer_counter) breaktime()""" #get data and pass them from camera to img cam.get_image(img) data_raw_calib = img.get_image_data_numpy() #exposure time PID max_val_calib = np.amax(data_raw_calib) #max_vals = np.append(max_vals, ([max_val]),axis=0) if (max_val_calib > 0): output = pid(max_val_calib) new_exp = new_exp + output if (new_exp < 100): new_exp = 100 new_exp = (round(new_exp / 5)) * 5 new_exp = int(new_exp) if (initial_calib_done == 1): print("Set_%s - Exposure calibration: %s" % (dataset_num + 1, new_exp)) else: print("Initial Exposure Calibration: %s" % (new_exp)) if (new_exp < exp_limit and new_exp > 0): cam.set_exposure(new_exp) else: return
def controlTemp(mean_Temp): if (mean_Temp > 0): datetime_Now = datetime.strptime( datetime.now().strftime("%m/%d/%Y, %H:%M:%S"), "%m/%d/%Y, %H:%M:%S" ) #Fait comme ca pour avoir la meme forme que les autres datetimes. Sinon des erreurs de precisions arrivent. datetime_On_Heat = datetime.strptime(obj_Control.heat_On_Time, "%m/%d/%Y, %H:%M:%S") datetime_Off_Heat = datetime.strptime(obj_Control.heat_Off_Time, "%m/%d/%Y, %H:%M:%S") if (datetime_Now > datetime_Off_Heat and datetime_Now > datetime_On_Heat): obj_Control.heat_On_Time = datetime_Now.strftime( "%m/%d/%Y, %H:%M:%S") obj_Control.heat_Off_Time = ( datetime_Now + timedelta(seconds=obj_Control.PERIOD_HEAT) ).strftime("%m/%d/%Y, %H:%M:%S") elif (datetime_Now >= datetime_Off_Heat ): #Lorsque tempsoff est depassé, allume et set le temps max On try: pid_Heating = PID(10, 5, 3, setpoint=obj_Control.setpoint_Temp) pid_Heating.output_limits = ( 0, obj_Control.PERIOD_HEAT ) #Fait un output de 0 a 5 qui sera changé en secondes temp_Control = pid_Heating(mean_Temp) except: print("Erreur Heating Control") if (obj_Control.heating_On == False): obj_Control.heating_On = True obj_Control.heat_On_Time = ( datetime_Off_Heat + timedelta(seconds=(int(temp_Control)), milliseconds=(temp_Control * 1000) % 1000)).strftime("%m/%d/%Y, %H:%M:%S") obj_Control.heat_Off_Time = ( datetime_Off_Heat + timedelta(seconds=obj_Control.PERIOD_HEAT) ).strftime("%m/%d/%Y, %H:%M:%S") obj_Control.toggle(obj_Control.PIN_CHAUFFAGE) #print("Heating On - Time : {} -> Heat Shutoff : {} - New Cycle : {}".format(datetime_Now.strftime("%m/%d/%Y, %H:%M:%S"),obj_Control.heat_On_Time, obj_Control.heat_Off_Time)) elif (datetime_Now >= datetime_On_Heat): if (obj_Control.heating_On == True): #print("Shutting off Heat. - Time : {}".format(datetime_Now.strftime("%m/%d/%Y, %H:%M:%S"))) obj_Control.heating_On = False obj_Control.toggle(obj_Control.PIN_CHAUFFAGE)
def main(): try: # it may need to get adjusted according to the value that the material from pipeline base reflects to the infrared default_speed = 400 pid = PID(12, 0, 2, setpoint=setpoint) side_k_to_rotate = 15 front_k_to_rotate = 5 rotation_speed = 40 speed_a = 0 speed_b = 0 while True: side_distance = robot.get_side_dist_pipeline_flw() front_distance = robot.get_front_dist_pipeline_flw() control = pid(side_distance) # print(side_distance) if side_distance > side_k_to_rotate: robot.stop_motors() robot.move_timed(0.7, speed=-1000) robot.rotate(-90, axis="own", speed=200) if front_distance < front_k_to_rotate: robot.stop_motors() robot.rotate(90, axis="own", speed=200) speed_a = control - default_speed speed_b = -control - default_speed if speed_a >= 1000: speed_a = 1000 elif speed_a <= -1000: speed_a = -1000 if speed_b >= 1000: speed_b = 1000 elif speed_b <= -1000: speed_b = -1000 robot.motors.left.run_forever(speed_sp=speed_a) robot.motors.right.run_forever(speed_sp=speed_b) except KeyboardInterrupt: robot.stop_motors()
def main(): global quit, out, control, err fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('.\CV_DS\debug_1.avi', fourcc, fps, frame_size) keyboard.on_press_key("1", toggle_quit, suppress=True) pid = PID(1, 0.1, 0.05, setpoint=1) pid.sample_time = 1 print("Press 1 to start") while quit: sleep(1) print("Press 1 to quit") while not quit: frame = np.array(ImageGrab.grab()) err = get_err(frame) control = pid(err) update(control, err) cv2.destroyAllWindows() keyboard.unhook_all() out.release()
def __init__(self): p = rospy.get_param('~p', 1) i = rospy.get_param('~i', 0.1) d = rospy.get_param('~d', 0.05) input_topic = rospy.get_param('~input') adjusted_topic = rospy.get_param('~adjusted') setpoint_topic = rospy.get_param('~setpoint') configuration_topic = rospy.get_param('~configuration') publish_rate = rospy.get_param('~publish_rate', 100) rospy.Subscriber(input_topic, Float64, self.inputCallback, queue_size=1) rospy.Subscriber(setpoint_topic, Float64, self.setpointCallback, queue_size=1) rospy.Subscriber(configuration_topic, Float64MultiArray, self.configurationCallback, queue_size=1) self.publisher = rospy.Publisher(adjusted_topic, Float64, queue_size=1) self.message = Float64() self.rate = rospy.Rate(publish_rate) self.pid = PID(p, i, d)
def test_error_map(): import math def pi_clip(angle): """Transform the angle value to a [-pi, pi) range.""" if angle > 0: if angle > math.pi: return angle - 2 * math.pi else: if angle < -math.pi: return angle + 2 * math.pi return angle sp = 0.0 # Setpoint pv = 5.0 # Process variable pid = PID(1, 0, 0, setpoint=0.0, sample_time=0.1, error_map=pi_clip) # Check if error value is mapped by the function assert pid(pv) == pi_clip(sp - pv)
def test_converge_system(): pid = PID(1, 0.8, 4, setpoint=5, output_limits=(-5, 5)) PV = 0 # process variable def update_system(C, dt): # calculate a simple system model return PV + C*dt - 1*dt start_time = time.time() last_time = start_time while time.time() - start_time < 120: C = pid(PV) PV = update_system(C, time.time()-last_time) last_time = time.time() # check if system has converged assert abs(PV - 5) < 0.1
def test_converge_system(): pid = PID(1, 0.8, 0.04, setpoint=5, output_limits=(-5, 5)) pv = 0 # Process variable def update_system(c, dt): # Calculate a simple system model return pv + c * dt - 1 * dt start_time = time.time() last_time = start_time while time.time() - start_time < 120: c = pid(pv) pv = update_system(c, time.time() - last_time) last_time = time.time() # Check if system has converged assert abs(pv - 5) < 0.1