<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Defining the Problem
Here we will derive the equations of motion for the classic mass-spring-damper system under the influence of gravity. The following figure gives a pictorial description of the problem.
Step1:  Start by loading in the core functionality of both SymPy and Mechanics.
Step2:  We can make use of the pretty printing of our results by loading SymPy's printing extension, in particular we will use the vector printing which is nice for mechanics objects.
Step3:  We'll start by defining the variables we will need for this problem
Step4:  Now, we define a Newtonian reference frame that represents the ceiling which the particle is attached to, $C$.
Step5:  We will need two points, one to represent the original position of the particle which stays fixed in the ceiling frame, $O$, and the second one, $P$ which is aligned with the particle as it moves.
Step6:  The velocity of point $O$ in the ceiling is zero.
Step7:  Point $P$ can move downward in the $y$ direction and its velocity is specified as $v$ in the downward direction.
Step8:  There are three forces acting on the particle. Those due to the acceleration of gravity, the damper, and the spring.
Step9:  Now we can use Newton's second law, $0=F-ma$, to form the equation of motion of the system.
Step10:  We can then form the first order equations of motion by solving for $\frac{dv}{dt}$ and introducing the kinematical differential equation, $v=\frac{dx}{dt}$.
Step11:  Forming the equations of motion can also be done with the automated methods available in the Mechanics package
Step12:  Now we can construct a KanesMethod object by passing in the generalized coordinate, $x$, the generalized speed, $v$, and the kinematical differential equation which relates the two, $0=v-\frac{dx}{dt}$.
Step13:  Now Kane's equations can be computed, and we can obtain $F_r$ and $F_r^*$.
Step14:  The equations are also available in the form $M\frac{d}{dt}[q,u]^T=f(q, u)$ and we can extract the mass matrix, $M$, and the forcing functions, $f$.
Step15:  Finally, we can form the first order differential equations of motion $\frac{d}{dt}[q,u]^T=M^{-1}f(\dot{u}, u, q)$, which is the same as previously found.
Step16:  Simulating the system
Now that we have defined the mass-spring-damper system, we are going to simulate it.
PyDy's System is a wrapper that holds the Kanes object to integrate the equations of motion using numerical values of constants.
Step17:  Now, we specify the numerical values of the constants and the initial values of states in the form of a dict.
Step18:  We must generate a time vector over which the integration will be carried out. NumPy's linspace is often useful for this.
Step19:  The trajectory of the states over time can be found by calling the .integrate() method.
Step20:  Visualizing the System
PyDy has a native module pydy.viz which is used to visualize a System in an interactive 3D GUI.
Step21:  For visualizing the system, we need to create shapes for the objects we wish to visualize, and map each of them 
to a VisualizationFrame, which holds the position and orientation of the object. First create a sphere to represent the bob and attach it to the point $P$ and the ceiling reference frame (the sphere does not rotate with respect to the ceiling).
Step22:  Now create a circular disc that represents the ceiling and fix it to the ceiling reference frame. The circle's default axis is aligned with its local $y$ axis, so we need to attach it to a rotated ceiling reference frame if we want the circle's axis to align with the $\hat{c}_x$ unit vector.
Step23:  Now we initialize a Scene. A Scene contains all the information required to visualize a System onto a canvas.
It takes a ReferenceFrame and Point as arguments.
Step24:  We provide the VisualizationFrames, which we want to visualize as a list to scene.
Step25:  The default camera of Scene has the z axis of the base frame pointing out of the screen, and the y axis pointing up. We want the x axis to point downwards, so we supply a new camera that will achieve this.
Step26:  Now, we call the display method.
<ASSISTANT_TASK:>
Python Code:
from IPython.display import SVG
SVG(filename='mass_spring_damper.svg')
Explanation: Defining the Problem
Here we will derive the equations of motion for the classic mass-spring-damper system under the influence of gravity. The following figure gives a pictorial description of the problem.
End of explanation
import sympy as sym
import sympy.physics.mechanics as me
Explanation: Start by loading in the core functionality of both SymPy and Mechanics.
End of explanation
from sympy.physics.vector import init_vprinting
init_vprinting()
Explanation: We can make use of the pretty printing of our results by loading SymPy's printing extension, in particular we will use the vector printing which is nice for mechanics objects.
End of explanation
x, v = me.dynamicsymbols('x v')
m, c, k, g, t = sym.symbols('m c k g t')
Explanation: We'll start by defining the variables we will need for this problem:
- $x(t)$: distance of the particle from the ceiling
- $v(t)$: speed of the particle
- $m$: mass of the particle
- $c$: damping coefficient of the damper
- $k$: stiffness of the spring
- $g$: acceleration due to gravity
- $t$: time
End of explanation
ceiling = me.ReferenceFrame('C')
Explanation: Now, we define a Newtonian reference frame that represents the ceiling which the particle is attached to, $C$.
End of explanation
O = me.Point('O')
P = me.Point('P')
Explanation: We will need two points, one to represent the original position of the particle which stays fixed in the ceiling frame, $O$, and the second one, $P$ which is aligned with the particle as it moves.
End of explanation
O.set_vel(ceiling, 0)
Explanation: The velocity of point $O$ in the ceiling is zero.
End of explanation
P.set_pos(O, x * ceiling.x)
P.set_vel(ceiling, v * ceiling.x)
P.vel(ceiling)
Explanation: Point $P$ can move downward in the $y$ direction and its velocity is specified as $v$ in the downward direction.
End of explanation
damping = -c * P.vel(ceiling)
stiffness = -k * P.pos_from(O)
gravity = m * g * ceiling.x
forces = damping + stiffness + gravity
forces
Explanation: There are three forces acting on the particle. Those due to the acceleration of gravity, the damper, and the spring.
End of explanation
zero = me.dot(forces - m * P.acc(ceiling), ceiling.x)
zero
Explanation: Now we can use Newton's second law, $0=F-ma$, to form the equation of motion of the system.
End of explanation
dv_by_dt = sym.solve(zero, v.diff(t))[0]
dx_by_dt = v
dv_by_dt, dx_by_dt
Explanation: We can then form the first order equations of motion by solving for $\frac{dv}{dt}$ and introducing the kinematical differential equation, $v=\frac{dx}{dt}$.
End of explanation
mass = me.Particle('mass', P, m)
Explanation: Forming the equations of motion can also be done with the automated methods available in the Mechanics package: LagrangesMethod and KanesMethod. Here we will make use of Kane's method to find the same equations of motion that we found manually above. First, define a particle that represents the mass attached to the damper and spring.
End of explanation
kane = me.KanesMethod(ceiling, q_ind=[x], u_ind=[v], kd_eqs=[v - x.diff(t)])
Explanation: Now we can construct a KanesMethod object by passing in the generalized coordinate, $x$, the generalized speed, $v$, and the kinematical differential equation which relates the two, $0=v-\frac{dx}{dt}$.
End of explanation
fr, frstar = kane.kanes_equations([(P, forces)], [mass])
fr, frstar
Explanation: Now Kane's equations can be computed, and we can obtain $F_r$ and $F_r^*$.
End of explanation
M = kane.mass_matrix_full
f = kane.forcing_full
M, f
Explanation: The equations are also available in the form $M\frac{d}{dt}[q,u]^T=f(q, u)$ and we can extract the mass matrix, $M$, and the forcing functions, $f$.
End of explanation
M.inv() * f
Explanation: Finally, we can form the first order differential equations of motion $\frac{d}{dt}[q,u]^T=M^{-1}f(\dot{u}, u, q)$, which is the same as previously found.
End of explanation
from pydy.system import System
sys = System(kane)
Explanation: Simulating the system
Now that we have defined the mass-spring-damper system, we are going to simulate it.
PyDy's System is a wrapper that holds the Kanes object to integrate the equations of motion using numerical values of constants.
End of explanation
sys.constants = {m:10.0, g:9.8, c:5.0, k:10.0}
sys.initial_conditions = {x:0.0, v:0.0}
Explanation: Now, we specify the numerical values of the constants and the initial values of states in the form of a dict.
End of explanation
from numpy import linspace
sys.times = linspace(0.0, 10.0, 100)
Explanation: We must generate a time vector over which the integration will be carried out. NumPy's linspace is often useful for this.
End of explanation
x_trajectory = sys.integrate()
Explanation: The trajectory of the states over time can be found by calling the .integrate() method.
End of explanation
from pydy.viz import *
Explanation: Visualizing the System
PyDy has a native module pydy.viz which is used to visualize a System in an interactive 3D GUI.
End of explanation
bob = Sphere(2.0, color="red", material="metal")
bob_vframe = VisualizationFrame(ceiling, P, bob)
Explanation: For visualizing the system, we need to create shapes for the objects we wish to visualize, and map each of them 
to a VisualizationFrame, which holds the position and orientation of the object. First create a sphere to represent the bob and attach it to the point $P$ and the ceiling reference frame (the sphere does not rotate with respect to the ceiling).
End of explanation
ceiling_circle = Circle(radius=10, color="white", material="metal")
from numpy import pi
rotated = ceiling.orientnew("C_R", 'Axis', [pi / 2, ceiling.z])
ceiling_vframe = VisualizationFrame(rotated, O, ceiling_circle)
Explanation: Now create a circular disc that represents the ceiling and fix it to the ceiling reference frame. The circle's default axis is aligned with its local $y$ axis, so we need to attach it to a rotated ceiling reference frame if we want the circle's axis to align with the $\hat{c}_x$ unit vector.
End of explanation
scene = Scene(ceiling, O, system=sys)
Explanation: Now we initialize a Scene. A Scene contains all the information required to visualize a System onto a canvas.
It takes a ReferenceFrame and Point as arguments.
End of explanation
scene.visualization_frames = [bob_vframe, ceiling_vframe]
Explanation: We provide the VisualizationFrames, which we want to visualize as a list to scene.
End of explanation
camera_frame = ceiling.orientnew('Camera Frame','Axis', [pi / 2, ceiling.z])
camera_point = O.locatenew('Camera Location', 100 * camera_frame.z)
primary_camera = PerspectiveCamera(camera_frame, camera_point)
scene.cameras = [primary_camera]
Explanation: The default camera of Scene has the z axis of the base frame pointing out of the screen, and the y axis pointing up. We want the x axis to point downwards, so we supply a new camera that will achieve this.
End of explanation
scene.display_ipython()
Explanation: Now, we call the display method.
End of explanation
<END_TASK>