CanHap Lab 4: Controlled actuation using PID

Hannah Elbaggari
9 min readFeb 26, 2021

--

This week we were asked to create and effectively tune a PID controller with our Haply. I worked with Rubia on implementing tuning and a tracking movement, which really helped to bounce ideas off one another. We ended up doing different implementations overall, but somehow ended up doing a similar shape. Big s/o to all of my lab mates who talked on Discord and Slack for this one, definitely subsided some of the confusion and lost feelings.

1. Run the code and try out the P controller. How does it feel? What happens when you change the target position? What does changing the P parameter do? Do you notice any problems?

Running the P controller was interesting. I think I have tried out something with the other Haply in a study once, so it felt somewhat familiar to me. When increasing the P, it would have a target point that if you are over it with the end effector, you do not feel any force. As you move away from the target, a vector is drawn and proportional force is provided as you move further away from the target. Tracing the area in which there is noticeable force when moving away from the target, the overall shape formed an oval. The visual cues of the vector moving proportionally helped communicate the increasing force. I also confirmed this by moving the end effector further away from the target.

As I changed the position of the target the end effector would gravitate towards the target in each new changed location. A potential problem I noticed here was that I had to initiate moving the end effector away from the calibration point to initiate the P response.

One problem I noticed was as I continually increased P and as I moved the end effector back to the target position, if I didn’t hold it the end effector would pull a too hard to the target. I know we were warned about this damaging the motors on Discord, so I tested how much I had to hold the end effector without letting it get out of control. Another problem I noticed was that while the force was low, the force around the target felt relatively smooth, like drawing an oval. As I increased the force, the smoothness as I moved around comfortably against the force became more choppy, as if there were force hotspots.

Lastly, only increasing the P would overshoot the target. It would do a sort of bouncing back when the P was high and the end effector was pulled towards the target.

I also played around with changing the shape of the target to further my understanding of how it was simulated. When I changed the target shape from [target = createShape(ELLIPSE, 0, 0, 20, 20);]

[target = createShape(ELLIPSE, 0, 0, 20, 20);]

to [ target = createShape(ELLIPSE, 0, 40, 20, 100);], a similar thing happened overall, but the ellipse target size was more of an oval shape.

[ target = createShape(ELLIPSE, 0, 40, 20, 100);]

Because of this as I moved around on the workspace, the force around the resized target shifted as expected to reflect the new size. One thing I did not expect was that when I changed the shape, the force on the upper parts of the target did not output as much force as I expected, this may have been due to the change of shape of the simulated target. I also think that it may have been due to the system accounting for not having to fight the motors to get the end effector back to the calibration point, but from further testing, it seems that this is not the case most of the time.

2. Add the D component to your controller. Tip: You can use a high smoothing (close to 1) to better see the effect of the derivative filter when manually moving the handle, but this adds delay and should be reduced for improving the stability. How does this change the behaviour of the Haply? Are there any problems?

While playing around with the D component, I realized the keypresses were much easier to use rather than the dials in the GUI. This was because I was able to more carefully increment the P and D parameters, thus adjustment and tuning was more straight forward. Precision of the mouse was very difficult to accomplish for me. Using the keypresses didn’t make any changes in the GUI so I printed the P, I, D, smoothing, and looptime values to keep track of everything. This can be seen in both videos linked below.

Added the link between the GUI and keyPressed functions so that when I pressed a key the visual in the GUI would show how much I have adjusted. This helped in not having to print out the PID values anymore

I did not end up using smoothing until after I had the P and D tuned. I went in the order of raising the P to about 0.8 and slowly increased the D. I used the approach of raising one parameter until just before instability and then raising the others. Raising the D parameter too hight resulted in a lot of oscillation.

This changed the behaviour of the Haply. With the D tuned, the end effector did not overshoot the target as much. I achieved stability with the D at 0.3. I tested this by using the random position to change the set point and feel the end effector guide me to the new target.

3. Add the I component to your controller. How does this change the behaviour of the Haply? Can you create a stable system that reaches the target?

Adding the I component added a lot of instability and was very difficult to tune. I felt as though this mostly just threw my tuning off when I increased the I even by 0.00001.

After a lot of trial and error, I found that by adjusting the P higher and I very low, I was able to tune the PID. Here was my output reading:

[P: 0.23000003, I: 1.01E-12, D: 0.20000002, smoothing: 0.8, looptime: 500]

With this finding, I have concluded that the I counters the force essentially making it more stable than my PD controller. When I was changing direction quickly, using this feature of the I helped quite a bit. When it was a small change I found that it would overcorrect so tuning with the I is still something I am not 100% sure is necessary if the P and the D are working well.

4. Implement path tracking, specifically, replace the random position by a position following a track over time (e.g., a circle or square). What happens when you hold the handle ? How is it affected by the PID parameters?

I tracked a right angle shape. I used the random target to point to a random starting point and it would follow a track in a line until it reaches a direction change point, changes direction and when it reaches the end, starts at the starting position again. I decided to use the looptime to track the new locations over time. Each loop would add 0.01 to the current position moving the target position forward. This video below shows the path tracking.

For this video I had to lightly hold the end effector when I changed location. This was mostly out of worry that the randomly generated location would end up somewhere outside of the Haply reach (which has happened before) so this was just a precautionary measure.

By holding the handle I added dampening to the PID. I had to adjust the P and D parameters to account for this and when I reached close to the full extension arms of the Haply, I found that it was a bit unstable. I wonder if any of this comes from the reach of the arms and dampening force from my hand when agains the motors in this position. I wasn’t able to figure out how to tune the PID to account for the oscillation in the bottom portions of the workspace.

As you can see in the above video, I had tracking on going pretty fast. This resulted in jerky movements that would throw the system out of tuning and become very unstable. I adjusted the parameters in which the system would track the target set point and got a much more controlled result.

(Left)I created a save variable to save the random start position of xr and yr. (Middle) Here I assigned savexr and saveyr to their start positions. (Right) implementation of using savexr and saveyr to compare the position of the end effector to draw the L shape

A slight instability that I was not able to figure out how to handle was when the random point would generate pretty low on the workspace. The problem can be seen at about [00:00:20] in the video. My hand was always ready to catch the arms to make sure I didn’t break it, hah.

5. Play with the controller update rates, and with introducing delays. Hint: use the “looptime” parameter. How does this change the system? What happens if you sample faster or slower? What happens if it’s random (this would require some coding)?

In the video below I start with the looptime parameter all the way up. As seen in the video, the delays allow the end effector to move around the target. This impacts the tuning of the PID quite a bit since the end effector was very unstable and oscillating around the target. In the video below I slowly lower the loop time which brings the PID back to a stable state from the previously tuned controller.

As seen in the video, when looptime was low (250) the system would check the target point often while correcting its direction (as seen by the movement of the arrow in the video). When looptime was high, this allowed for a lot of extra movement, oversteering in this case.

I also attempted to then tune the PID with the looptime and found that this was not possible to do without increasing the I a bit. Below is a photo of my tuned PID when trying to tune with looptime higher than 750.

When sampling with a lower looptime, the PID controller tends to move in a controlled, yet quick movement. It feels a bit frantic. When sampling with a higher looptime, the movement is slower, but so is the allowance of other non-guided movements.

Reflection

I will begin this discussion with the caveat that I have never taken a control theory course. A lot of this was new to me, so I think I have communicated my understanding of the PID controller in the best way I could. It definitely helped my understanding to learn by doing in this case––I found myself a bit lost in the theory of it all, so grounding my understanding in the application of an example really helped.

To help my understanding while understanding and tuning for this lab I used this video as well as a reddit ELI5 post so I knew where to begin. I also got on a call with Rubia since we were meeting to discuss our project as well. We got to the point of implementing some tracking movement together which was really helpful and I shared small things like the keypresses as we discussed how to tune as well.

Tuning was one thing that took some getting used to. I didn’t see the purpose of the I component for a while since I was reaching a stable state with the P and D. What was helpful was the discussion on Discord (yesterday I think) that told us to reset the integrator because even if it is set at 0 it would continue to add error. This would explain my results in question 3 wherein I was unable to get a stable state, but when I reset the integrator (by just stopping and rerunning the simulation) I was able to reach a stable state eventually.

Find code here

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response