-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
132 lines (105 loc) · 3.74 KB
/
Copy pathmain.py
File metadata and controls
132 lines (105 loc) · 3.74 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 10 10:18:55 2025
@author: adiazfl
Validated
"""
# Python libraries
import numpy as np
import sympy as sym
import matplotlib.pyplot as plt
from time import time
# Custom modules
from multibody import MbdSystem
import multibody as mbd
from multibody import load_yaml_as_example
############ Example to import ############
# from Examples_mbd import n_pendulum as ex
############ Example to import ############
folder = 'Examples_yaml/'
ex_file = 'slider_w_dpend' # Example file to import
# Load the example from the YAML file
ex = load_yaml_as_example(folder + ex_file)
# 1- Initialize the Multibody system
MBDsys = MbdSystem.from_example(ex)
# 3 - Define initial numerical values
mainNumVars = np.hstack((MBDsys.ic, ex.ForcesPointsNum, ex.BodyDataNum))
print('Finished initialization')
# 3 - Integrate over time
sol = MBDsys.integrate(mainNumVars, ex.m0, ex.J0,
tspan=ex.tspan, dt=ex.TimeStep) # ❷ run
com_positions, com_velocities, angle_positions, joint = mbd.evaluate_trajectories(MBDsys, sol, mainNumVars)
############### Plotting ###############
# Multibody connections graph plot
# MBDsys.graph.show()
# Create figure with 3 subplots for x, z, and pitch DOF
fig, axes = plt.subplots(3, 1, figsize=(10, 8))
# Plot x position for all bodies
for body in range(len(com_positions[1])):
axes[0].plot(sol.t, com_positions[:, body, 0], label=f'Body {body+1}')
axes[1].plot(sol.t, com_positions[:, body, 1], label=f'Body {body+1}')
axes[2].plot(sol.t, angle_positions[:, body]*180/np.pi, label=f'Body {body+1}')
axes[0].set_xlabel('Time [s]')
axes[0].set_ylabel('x [m]')
axes[0].set_title('X Position')
axes[0].legend()
axes[0].grid(True)
axes[1].set_xlabel('Time [s]')
axes[1].set_ylabel('z [m]')
axes[1].set_title('Z Position')
axes[1].legend()
axes[1].grid(True)
axes[2].set_xlabel('Time [s]')
axes[2].set_ylabel('Pitch [deg]')
axes[2].set_title('Pitch Angle')
axes[2].legend()
axes[2].grid(True)
plt.tight_layout()
plt.show()
# Plot energy
Em_num = []
for i, ti in enumerate(sol.t):
mainNumVars_copy = mainNumVars.copy()
mainNumVars_copy[:len(sol.y)] = sol.y[:,i]
mainNumVars_copy[MBDsys.t_update] = ti
Em_num.append(MBDsys.Energy_func(*mainNumVars_copy,
*ex.m0, *ex.J0))
Em_num = np.array(Em_num)
fig, ax = plt.subplots(figsize=(8,4))
mbd.plot.plt_template(ax, dark=False)
ax.plot(sol.t, Em_num, lw=1.8)
ax.set_xlabel("t [s]"); ax.set_ylabel("E [J]")
ax.set_title("Total mechanical energy")
plt.tight_layout(); plt.show()
# Initial time plot
frame_tol = 0.2
frame_bounds = mbd.plot.bound_finder(frame_tol, sol.t, sol.y ,mainNumVars, MBDsys)
# Optional time value
current_time = 0.0
current_vars = mainNumVars.copy()
current_vars[:len(sol.y)] = sol.y[:,0]
current_vars[MBDsys.t_update]= current_time # update time-dependent variables
# Call the plot function
fig, ax = mbd.plot.plot_multibody_system(
main_num_vars = current_vars,
MBD = MBDsys,
t_val = current_time,
frame_bounds = frame_bounds,
dark_mode = False # Or True for dark background
)
# plt.tight_layout()
plt.show() # or fig.savefig('snapshot.png')
#%% Animation
if ex.animation_on:
anim = mbd.plot.animate_multibody(
tvec = sol.t[::ex.plotTstep],
y = sol.y[:,::ex.plotTstep],
MBD = MBDsys,
mainNumVars = mainNumVars.copy(),
frame_bounds = frame_bounds,
save_path = ex.SaveMovieOn, # ".gif" ➜ GIF · None ➜ just show
fps = 100,
loop = False,
)
plt.close()
print('\nReached end')