Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to work with control namely PID controller #240

Open
Tomke997 opened this issue Sep 16, 2023 · 0 comments
Open

How to work with control namely PID controller #240

Tomke997 opened this issue Sep 16, 2023 · 0 comments

Comments

@Tomke997
Copy link

Tomke997 commented Sep 16, 2023

Hi,

I am using this library for parameter estimation of a cruise control system with PID controller. My task is to represent my system as an ODE and predict control parameters namely Kp, Ki, Kd. Because of the nature of the PID controller, I have to use fixed-step solvers which is not ideal especially when using adjoint. Because of the removal of grid_points and eps, I am not able to force the solver to 'move forward'. I wanted to ask if there is a workaround for those issues. Thanks in advance!

Here is the code for my model:

class Cruise_model(torch.nn.Module):
    def __init__(self, solver, adjoint, parameters = None):
        # Call the super class initializer. 
        super(Cruise_model, self).__init__();

        # Set model parameters.
        self.Params = None
        self.Setpoint = 50.0/3.6
        self.Dt = 0.010
        self.Error_previous = 0.0
        self.Veh_drag_coeff = 0.33                             # Vehicle aerodynamic drag coefficient [N/m^2.s^2]
        self.Veh_height = 57.3 * 25.4/1000                     # Vehicle height [m]
        self.Veh_width = 69.9 * 25.4/1000                      # Vehicle width [m]
        self.Veh_drag_xA = self.Veh_width*self.Veh_height                # Effective front cross-sectional area [m^2]
        self.CdA = self.Veh_drag_coeff * self.Veh_drag_xA
        self.M = 2860/2.25 
        self.solver = solver
        self.adjoint = adjoint
        self.StartPoint = None
        
        self.x0 = None
        self.t = None
    
    def forward(self, t, x):              
        y, E = x
        dydt = torch.zeros_like(x)
        
        workaround_int = y + y.trunc().detach() - y.detach()
        error = self.Setpoint - workaround_int  
        inte = E 
        
        pid = self.Params[0]*error + self.Params[1]*inte + self.Params[2]*(error - self.Error_previous)/self.Dt
        F_ego = pid
        
        D_ego = self.CdA*(y ** 2)
        
        if y > 0:
            F_net = F_ego - D_ego
        else:
            F_net = F_ego + D_ego

        dydt[0] = F_net/self.M
        dydt[1] = error
        
        self.Error_previous = error
        return dydt
    
    def solve_ode(self, sp, t, params = None): # used for some optimization methods
        if params is not None:
            self.Params = params
        self.StartPoint = sp
        self.x0 = torch.tensor([self.StartPoint, (self.Setpoint - int(self.StartPoint))*self.Dt/2])
        self.t = t
        self.Error_previous = 0.0
        
        if self.adjoint:
            return odeint_adjoint(self.forward, self.x0, self.t, method = self.solver, options=dict(step_size=self.Dt), adjoint_params=list(self.parameters()) + [self.Params]) 
        else:
            return odeint(self.forward, self.x0, self.t, method = self.solver, options=dict(step_size=self.Dt)) 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant