First of all, I'm just a measly IT student and have very limited physics knowledge, so sorry, if my mistake is super obvious.
So basically I am trying to simulate a robot with a torsion spring in its knee (see picture) and measure what forces are applied to the knee joint and how much the spring deforms.
The program I've written produces graphs that have the correct shape, but for some reason the angle of the spring seems to be scaling with the size of my timesteps, which is definitely not correct.
I have attached my code below, but here is also a detailed explanation of what I think I am doing:
I assume that besides gravitation, there is only one force ever applied to the robot, and that force is applied at the start for a certain duration and is aimed straight down. From that force I calculate the angular velocity of my joint.
After that, I enter a loop where in every timestep I update the forces and the angle of the spring. I calculate the gravitational force dependent on the angle. I assume that my model resembles an inverted pendulum, and that the term for the mass of the leg is negligible. Then I calculate the counterforce exerted by the spring, and get the total force from the difference between the two.
I calculate the velocity change from the force, and update the velocity. From the velocity I get the change in angle and update the angle as well. I repeat that loop until a time limit is reached.
The rest of the code is just for plotting.
For some reason, the scale of the angle changes drastically with the size of the timesteps I choose. Other than that, however, the graphs look as I would expect: Oscillating briefly and then settling on one value. One problem I see is that the force of the spring directly depends on the timestep, while the gravitational force does not. Since everything else depends on the difference between the two forces, this changes the scale. However, I do not know how to fix this.
Thanks for any help!
import math
from scipy import constants
import matplotlib.pyplot as plt
class Spring:
def __init__(self, k, l=0.17, m=6.0):
self.k = k
self.l = l
self.m = m
self.alphaplt = []
self.forceplt = []
def impulse(self, force, duration, at_angle, stept):
time = 0
alpha = at_angle
i = self.m * self.l ** 2
vk = (force / self.m * duration) / self.l
while time <= 100:
tm = 0.5 * self.m * constants.g * self.l * math.sin(alpha)
tf = self.k * vk * stept / self.l
tg = tm - tf
vk = vk + (tg * stept * self.l) / i
alpha = alpha + vk * stept
time += stept
self.alphaplt.append(alpha)
self.forceplt.append(tg)
plt.plot(self.alphaplt)
plt.show()
plt.plot(self.forceplt)
plt.show()
if __name__ == "__main__":
s = Spring(0.75)
s.impulse(90, 0.5, 0, 0.01)