Cleaning up.

This commit is contained in:
Andru Liu
2024-10-07 23:36:01 -07:00
parent e9dc24a7a7
commit 042cf1a65a
6 changed files with 7 additions and 7 deletions
+122
View File
@@ -0,0 +1,122 @@
import tensorflow as tf
class RBFLayer(tf.keras.layers.Layer):
""" RBF Layer using TF Subclassing API.
...
Attributes
----------
n_centers : int
The number of RBF centers.
input_dim : int
The dimensions of the RBF centers.
Methods
-------
call(inputs):
TF call method to implement forward pass.
"""
def __init__(self, n_centers, input_dim):
""" Constructs RBF centers and standard deviations as trainable weights.
Parameters
----------
n_centers : int
The number of RBF centers.
input_dim : int
The dimensions of the RBF centers.
"""
super().__init__()
self.n_centers = n_centers
self.centers = self.add_weight(shape=(n_centers, input_dim),
initializer="random_normal",
trainable=True,)
self.sigmas = self.add_weight(shape=(n_centers,),
initializer="ones",
trainable=True,)
def call(self, inputs):
""" Find likelihood of inputs under Gaussian distribution given center and
standard deviation.
Parameters
----------
inputs : tensor
The points in space to evaluate the Gaussian.
Returns
-------
Height of Gaussian curve at inputs.
"""
distances = tf.norm(tf.expand_dims(inputs, axis=1) - self.centers, axis=2)
rbf_output = tf.exp(-tf.square(distances) / (2 * tf.square(self.sigmas)))
return rbf_output
class RBFAdaptiveModel(tf.keras.Model):
""" RBF Adaptive Model using TF Subclassing API.
Outputs one control signal adaptation. Determined by output layer
number of neurons.
...
Attributes
----------
n_centers : int
The number of RBF centers.
imput_dim : int
The dimensions of the RBF centers.
Methods
-------
call(inputs):
TF call method to implement forward pass of model.
"""
def __init__(self, n_centers, input_dim=3):
""" Constructs RBF and output layers.
Parameters
----------
n_centers : int
The number of RBF centers.
input_dim : int
The dimensions of the RBF centers. Default of 3 for Kp, Ki, Kd
"""
super().__init__()
self.rbf_layer = RBFLayer(n_centers, input_dim)
self.output_layer = tf.keras.layers.Dense(1)
def call(self, inputs):
""" Implement forward pass.
Parameters
----------
inputs : tensor
The points in space to adapt with.
Returns
-------
Adapted control signal.
"""
rbf_output = self.rbf_layer(inputs)
control_signal = self.output_layer(rbf_output)
return control_signal
def train_rbf_adaptive(model, errors, control_signals, epochs=100):
""" Training method for the RBF adaptive model.
Parameters
----------
model : RBFAdaptiveModel
A RBF Adaptive Model instance.
errors : ndarray
Multi-sample training data, [error, derivative, integral].
control_signals : ndarray
Control signal target values.
epochs : int
Number of epochs to train for.
"""
model.compile(optimizer="adam", loss="mean_squared_error")
model.fit(errors, control_signals, epochs=epochs, verbose=1)
+75
View File
@@ -0,0 +1,75 @@
import tensorflow as tf
class AdaptivePIDTf:
""" PID class implemented for TensorFlow integration.
...
Attributes
----------
Kp : float
Proportional gain.
Ki : float
Integral gain.
Kd : float
Derivative gain.
rbf_model : RBFAdaptiveModel object
RBF adaptive model class instance.
Methods
-------
update(target, measured_value, dt):
Updates the control signal.
"""
def __init__(self, Kp, Ki, Kd, rbf_model):
""" Constructs PID gains, RBF model, and initial PID components.
Parameters
----------
Kp : float
Proportional gain.
Ki : float
Integral gain.
Kd : float
Derivative gain.
rbf_model : RBFAdaptiveModel object
RBF adaptive model class instance.
"""
self.Kp = Kp
self.Ki = Ki
self.Kd = Kd
self.rbf_model = rbf_model
self.prev_err = 0
self.error = 0
self.integral = 0
self.derivative = 0
def update(self, target, measured_value, dt):
""" Update the control signal according to error and adapt with RBF
model predictions.
Parameters
----------
target : float
Target setpoint.
measured_value : float
Actual value.
dt : float
Timestep.
Returns
-------
Control signal.
"""
self.error = target - measured_value
self.integral += self.error * dt
self.derivative = (self.error - self.prev_err) / dt
u = (self.Kp * self.error) + (self.Ki * self.integral) + (self.Kd*self.derivative)
control_signal_adapt = self.rbf_model(tf.constant([[self.error, self.integral, self.derivative]])).numpy().flatten()[0]
u += control_signal_adapt
self.prev_err = self.error
return u