Goals: For this assignment, we are interested in creating a motion of one of the pendulum trying to bounce the ball while the other helps it when it loses control.
Process and outcome: We worked off the ndblpend_spirals.py and started with changing the phase and radius to make ball to move in an up and down direction. Then, we modified the endpoints of both pendulums and added a small damping point for the first arm so the ball catching movement is more fluid, while keeping the other guiding arm less flexible.
Final Code:
class PendulumController(rcp.doublependulum.DoublePendulumController): def __init__(self): super().__init__() self.timestep = 0 # set stiffer position and damping gains self.kp = np.array((200.0, 100.0)) self.kd = np.array((32.0, 8.0)) return #================================================================ def setup(self): if self.identity == 0: self.write("""Pair of double-pendulum simulations. One moves the endpoint along a circular path, while the other tries to follow. """) return #================================================================ def compute_control(self, t, dt, state, tau): """Method called from simulator to calculate the next step of applied torques. :param t: time in seconds since simulation began :param state: four element numpy array with joint positions ``q`` and joint velocities ``qd`` as ``[q0, q1, qd0, qd1]``, expressed in radians and radians/sec :param tau: two element numpy array to fill in with the joint torques to apply ``[tau0, tau1]`` """ # phase cycles one revolution of the circular path angle every 8 seconds phase = 0.45 * np.pi * t # radius slowly cycles up and down again radius = 0 if self.identity == 0: self.kd = np.array((2.0, 1.0)) # the first robot chooses a target pose in robot coordinates based # on the inverse kinematics solution for a spiral path # end is the world-coordinate location of a point traveling around the spiral centered between the two arms end = np.array((1.25, 0.2 * np.sin(phase) - 1)) # solve for the joint angles for the given endpoint s1, s2 = self.model.endpointIK(end) # arbitrarily one solution as the target pose pose = s1 if self.timestep % 1000 == 0: self.write("Time: %f endpoint: %s" % (t, end)) self.world.set_marker(0, end) else: # end is the world-coordinate location of a point traveling around the spiral centered between the two arms end = np.array((1.25, -np.cos(phase))) # solve for the joint angles for the given endpoint s1, s2 = self.model.endpointIK(end) # arbitrarily one solution as the target pose pose = s1 if self.timestep % 1000 == 0: self.write("Time: %f endpoint: %s" % (t, end)) self.world.set_marker(0, end) # create a target state by extending the pose to include velocity target = np.concatenate((pose, np.zeros(2))) # calculate position and velocity error as difference from reference state qerr = target - state # apply PD control to reach the pose (no integral term) tau[0] = (self.kp[0] * qerr[0]) + (self.kd[0] * qerr[2]) tau[1] = (self.kp[1] * qerr[1]) + (self.kd[1] * qerr[3]) self.timestep += 1 return
Comments are closed.