Hello, Im trying to implement a Differential Dynamic Programming algorithm using pytorch and I keep getting:

RuntimeError: One of the differentiated Tensors appears to not have been used in the graph. Set allow_unused=True if this is the desired behavior.

I’ve seen numerous posts about this problem but I want able to grasp why it is happening in my code:

def optimize(

self,

x0: torch.Tensor,

x_goal: torch.Tensor,

N: int = None,

U0: torch.Tensor = None,

full_output: bool = False,

):

if not N and U0 is None:

raise ValueError(“You must provide either trajectory length N or initial control sequence U0”)

if U0 is not None:

N = len(U0)

U = U0.clone().detach().requires_grad_(True)

else:

assert N > 0

U = torch.rand(N, self.Nu, requires_grad=True) * 2 - 1 # Uniform between -1 and 1

def J(X, U):

total_cost = sum(self.inst_cost(X[i], U[i], x_goal) for i in range(len(U)))

total_cost += self.terminal_cost(X[-1], x_goal)

return total_cost

```
X = [x0.clone().detach().requires_grad_(True)]
for i in range(N):
X.append(self.dynamics(X[-1], U[i]))
X = torch.stack(X)
last_cost = J(X, U)
if full_output:
X_hist = [X.clone().detach()]
U_hist = [U.clone().detach()]
cost_hist = [last_cost.item()]
for iteration in range(self.max_iters):
Vx = torch.autograd.grad(self.terminal_cost(X[-1], x_goal), X[-1], retain_graph=True)[0]
```

The main that calls this optimization function is:

def f(x, u, constrain=True):

theta = torch.atan2(x[0], x[1])

theta_dot = x[2].detach()

torque = torch.tanh(u[0]) if constrain else u[0]

theta_dot_dot = -3 * G * torch.sin(theta + torch.pi) / (2 * L) + 3 * torque / (M * L**2)

theta += theta_dot * dt

theta_dot += theta_dot_dot * dt

return torch.stack([torch.sin(theta), torch.cos(theta), theta_dot])

def h(x, x_goal):

error = x - x_goal

Qt = 100 * torch.eye(3, dtype=torch.float32)

result = error.view(1, -1) @ Qt @ error.view(-1, 1)

return result.squeeze()

N = 100 # trajectory points

Nx = 3 # state dimension

Nu = 1 # control dimensionsx0 = torch.tensor([torch.sin(torch.tensor(torch.pi)), torch.cos(torch.tensor(torch.pi)), 0.0], requires_grad=True)

x_goal = torch.tensor([torch.sin(torch.tensor(0.0)), torch.cos(torch.tensor(0.0)), 0.0], requires_grad=True)

ddp = DDPOptimizer(Nx, Nu, f, g, h)

X, U, X_hist, U_hist, J_hist = ddp.optimize(x0, x_goal, N=N, full_output=True)

This implementatin is based on the following blog and code which mainly uses sympy and numy

Ill be happy for your help!