Examples#
A very simple example program using Copapy can look like this:
import copapy as cp
# Define variables
a = cp.value(0.25)
b = cp.value(0.87)
# Define computations
c = a + b * 2.0
d = c ** 2 + cp.sin(a)
e = cp.sqrt(b)
# Create a target (default is local), compile and run
tg = cp.Target()
tg.compile(c, d, e)
tg.run()
# Read the results
print("Result c:", tg.read_value(c))
print("Result d:", tg.read_value(d))
print("Result e:", tg.read_value(e))
Another example using autograd in Copapy, here implementing gradient descent to solve an inverse kinematics problem for a two-joint 2D arm:
import copapy as cp
# Arm lengths
l1, l2 = 1.8, 2.0
# Target position
target = cp.vector([0.7, 0.7])
# Learning rate for iterative adjustment
alpha = 0.1
def forward_kinematics(theta1, theta2):
"""Return positions of joint and end-effector."""
joint = cp.vector([l1 * cp.cos(theta1), l1 * cp.sin(theta1)])
end_effector = joint + cp.vector([l2 * cp.cos(theta1 + theta2),
l2 * cp.sin(theta1 + theta2)])
return joint, end_effector
# Start values
theta = cp.vector([cp.value(0.0), cp.value(0.0)])
# Iterative inverse kinematics
for _ in range(48):
joint, effector = forward_kinematics(theta[0], theta[1])
error = ((target - effector) ** 2).sum()
theta -= alpha * cp.grad(error, theta)
tg = cp.Target()
tg.compile(error, theta, joint)
tg.run()
print(f"Joint angles: {tg.read_value(theta)}")
print(f"Joint position: {tg.read_value(joint)}")
print(f"End-effector position: {tg.read_value(effector)}")
print(f"quadratic error = {tg.read_value(error)}")
Joint angles: [-0.7221821546554565, 2.6245293617248535]
Joint position: [1.3509329557418823, -1.189529299736023]
End-effector position: [0.6995794177055359, 0.7014330625534058]
quadratic error = 2.2305819129542215e-06