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

PID output is the same at every call? #90

Open
aaprasad opened this issue Oct 3, 2024 · 2 comments
Open

PID output is the same at every call? #90

aaprasad opened this issue Oct 3, 2024 · 2 comments

Comments

@aaprasad
Copy link

aaprasad commented Oct 3, 2024

Hi, I'm not sure if this is expected behavior but when I try running the PID controller with different inputs at each call it outputs the same value every time regardless of what gains I choose

for instance if I run

pid = PID(1, 0.5, 0.01, setpoint=1)
for _ in range(10):
    print(pid(np.random.normal()))

It will print the same value each time but my understanding is this should change no?

@m-lundberg
Copy link
Owner

Hi! The pid has a sample time and will only produce new values after the sample time has passed. Since your loop is very fast, it probably loops over all iterations before the sample time has passed. If you truly want a new value every time, you can set the sample time to None: pid.sample_time = None.

You can read more on this topic here.

@aaprasad
Copy link
Author

aaprasad commented Oct 4, 2024

I see, that makes a lot of sense! I'm trying to use your controller for what basically boils down to RL-based position control in gym so I'm not really sure what the right sample_time would be? Right now my control loop looks something like this:

def step(action):
      """Compute torques and take one environment step
           Args:
                   action: an n_joint x 1 vector of desired joint angles
           Returns:
                    obs, reward, terminated, truncated
      """
      torques = self.simulate(action)
      self.env.step(torques)

def simulate(actions, controller, substeps=10):
       """Forward simulate and tune torques using PD control
        
             Args:
                     actions: an n_joints x 1 vector of desired joint angles
                     controllers = a list of n_joints `PID` controllers for each joint
                     substeps: number of substeps to tune torque output
       """
       set_desired_joint_angles(actions, controllers) # sets the set point of each controller to corresponding joint angle
       og_state = self.env.get_state()
       predicted_joint_angles = self.env.get_joint_angles()

       for i in range(substeps):
            self.env.reset_state(og_state)
            torques = []
            for controller, joint_angle in zip(controllers, current_joint_angles):
                  torque = controller(joint_angle)
                  torques.append(torque)
            self.env.step(torques)
            predicted_joint_angles = self.env.get_joint_angles()

      return torques

In this case should I set the sample_time to 1/substeps and just override the time_function to return i/substep? where i is the ith substep?

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

2 participants