-
Notifications
You must be signed in to change notification settings - Fork 0
/
cart_pendulum_model.py
97 lines (79 loc) · 3.07 KB
/
cart_pendulum_model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import torch
from warnings import warn
from torch import cos, sin
class CartPole_motion():
'''Continuous version of the OpenAI Gym cartpole
Inspired by: https://gist.github.com/iandanforth/e3ffb67cf3623153e968f2afdfb01dc8'''
def __init__(self):
self.device = torch.device('cpu')
self.gravity = 9.81
self.masscart = 1.0
self.masspole = 0.1
self.total_mass = (self.masspole + self.masscart)
self.length = 0.5
self.polemass_length = (self.masspole * self.length)
self.model_std = 0
self.model_mean = 0
def dynamics(self, θ, dθ, u):
"""
Calculate the continuous equation of motion of the cartpole.
Parameters:
----------
θ : torch.Tensor
Current pole's angle.
dθ : torch.Tensor
Current pole's angular velocity.
u : torch.Tensor
Current control input.
Returns:
-------
torch.Tensor
A tensor containing the second derivatives of the pole's angle (ddθ) and the cart's velocity (ddx).
"""
# Auxiliary variables
cosθ, sinθ = torch.cos(θ), torch.sin(θ)
temp = (u + self.polemass_length * dθ**2 * sinθ) / self.total_mass
# Differential Equations
ddθ = (self.gravity * sinθ - cosθ * temp) / \
(self.length * (4.0/3.0 - self.masspole * cosθ**2 / self.total_mass))
ddx = temp - self.polemass_length * ddθ * cosθ / self.total_mass
return torch.row_stack([ddθ, ddx])
def motion_model(self,state, velocity, u, dt):
"""
This function implements the continuous time dynamics of the cartpole system.
Parameters
----------
dt : float
Time step size.
velocity : torch.Tensor
Previous Velocity of the cart.
state : torch.Tensor
Previous State of the cart.
u : float
Current Control input.
Returns
-------
state: torch.Tensor
Current state of the cartpole.
"""
accel = self.dynamics(state[0], velocity[0], u) + self.white_noise(state.size()).to(self.device)
velocity = velocity + dt*accel
state = state + dt*velocity
return torch.row_stack([state, velocity, accel])
def white_noise(self, size):
"""
Generate a tensor of white noise with the given size.
This function uses PyTorch's randn function to generate a tensor of random numbers
from a standard normal distribution. The generated noise is then scaled by the
model's standard deviation and shifted by the model's mean.
Parameters:
----------
size : tuple or torch.Size
The size of the output tensor.
Returns:
-------
noisy_data : torch.Tensor
A tensor of white noise with the given size.
"""
noisy_data = self.model_mean + torch.randn(size)*self.model_std**2
return noisy_data