projectchrono/chrono

Issue for setting multiple ChLinkMotorRotationSpeed

simzc opened this issue · 1 comments

simzc commented

Hi everyone,
I am using chrono to test the performance of multiple specified axes of rotation by implementing a rotation motion of the Earth while orbiting the Sun, but when I use two ChLinkMotorRotationSpeed applied to the rigid body of the Earth, the results of the simulation are not satisfactory.
For two or more ChLinkMotorRotationSpeed constraints, how can I achieve accurate results for multiple ChLinkMotorRotationSpeeds on a rigid body by having some of them move with the rigid body?
Any suggestions would be appreciated!

Chao

Here is my code using pychrono:

import pychrono.core as chrono
import pychrono.irrlicht as irr
import matplotlib.pyplot as plt

# create the system
sys = chrono.ChSystemNSC()
sys.Set_G_acc(chrono.ChVectorD(0.0, 0.0, 0.0))

chrono.ChCollisionModel.SetDefaultSuggestedMargin(0.001)
chrono.ChCollisionModel.SetDefaultSuggestedEnvelope(0.001)

# create the material
mat = chrono.ChMaterialSurfaceNSC()
mat.SetFriction(0.8)
mat.SetRestitution(0.4)

# create the cup
cup = chrono.ChBodyEasyMesh("cup.obj", 1000, False, True, False, mat, 0.0001)
cup.SetBodyFixed(True)
cup.SetFrame_COG_to_REF(chrono.ChFrameD(chrono.ChVectorD(0, 0, -0.1), chrono.ChMatrix33D(1)))
cup.SetMass(1)
sys.Add(cup)

# create the box
box = chrono.ChBodyEasyBox(0.005, 0.005, 0.005, 1000, True, True, mat)
box.SetBodyFixed(True)
sys.Add(box)

# create the egg
egg = chrono.ChBodyEasyMesh("egg_modify.obj", 1100, False, True, True, mat, 0.0001)
egg.SetBodyFixed(False)
egg.SetFrame_COG_to_REF(chrono.ChFrameD(chrono.ChVectorD(0.0, 0.0, 0.0301714398), chrono.ChMatrix33D(1)))
egg.SetFrame_REF_to_abs(chrono.ChFrameD(chrono.ChVectorD(0.125, 0.0, -0.125), chrono.ChMatrix33D(1)))
egg.SetMass(1)
sys.Add(egg)

# create the rotation motion
rot_const = chrono.ChFunction_Const(-chrono.CH_C_2PI)
imposed_motion_tra_x = chrono.ChLinkMotorRotationSpeed()
imposed_motion_tra_x.Initialize(egg, cup, chrono.ChFrameD(egg.GetPos()))
imposed_motion_tra_x.SetSpeedFunction(rot_const)
sys.Add(imposed_motion_tra_x)

# create the revolution motion
rev_const = chrono.ChFunction_Const(chrono.CH_C_2PI)
imposed_motion_rev = chrono.ChLinkMotorRotationSpeed()
imposed_motion_rev.Initialize(egg, cup, chrono.ChFrameD(cup.GetPos()))
imposed_motion_rev.SetSpeedFunction(rev_const)
sys.Add(imposed_motion_rev)

# Create the Irrlicht application
vis = irr.ChVisualSystemIrrlicht()
vis.AttachSystem(sys)
vis.SetWindowSize(1200, 800)
vis.SetWindowTitle('Imposing rotation on bodies')
vis.Initialize()
vis.AddLogo(chrono.GetChronoDataFile('logo_pychrono_alpha.png'))
vis.AddSkyBox()

vis.AddTypicalLights()
camera_per = chrono.CameraVerticalDir_Z
vis.SetCameraVertical(camera_per)
vis.AddCamera(chrono.ChVectorD(0.35, 0.35, 0.1))
vis.EnableBodyFrameDrawing(True)
vis.EnableCollisionShapeDrawing(False)

# monitor values
time = []
egg_vel_x_par = []
egg_vel_y_par = []
egg_vel_z_par = []
egg_vel_x_loc = []
egg_vel_y_loc = []
egg_vel_z_loc = []

# run the simulation
dt = 1e-3
while vis.Run():
    vis.BeginScene()
    vis.Render()
    vis.EndScene()

    t = sys.GetChTime()
    print(t)

    time.append(sys.GetChTime())
    egg_vel_x_par.append(egg.GetWvel_par().x)
    egg_vel_y_par.append(egg.GetWvel_par().y)
    egg_vel_z_par.append(egg.GetWvel_par().z)

    egg_vel_x_loc.append(egg.GetWvel_loc().x)
    egg_vel_y_loc.append(egg.GetWvel_loc().y)
    egg_vel_z_loc.append(egg.GetWvel_loc().z)

    sys.DoStepDynamics(dt)

    if sys.GetChTime() > 2:
        vis.GetDevice().closeDevice()

# plot the values
plt.plot(time, egg_vel_x_par, 'r--', label="egg_vel_x_par")
plt.plot(time, egg_vel_y_par, 'g--', label="egg_vel_y_par")
plt.plot(time, egg_vel_z_par, 'b--', label="egg_vel_z_par")
plt.plot(time, egg_vel_x_loc, 'r-*', label="egg_vel_x_loc")
plt.plot(time, egg_vel_y_loc, 'g-*', label="egg_vel_y_loc")
plt.plot(time, egg_vel_z_loc, 'b-*', label="egg_vel_z_loc")

plt.legend()
plt.title('egg vel')
plt.show()

simzc commented

I have just implemented a different way to simulate this problem. The general idea is to set two ChLinkMotorRotationSpeed. (1). When Initialize the revolution of egg, define a virtual rigid body as Master Frame, COG of cup as Slave Frame, and the speed as egg revolution speed. (2). For the rotation of egg, we define COG of cup as Master Frame, COG of egg as Slave Frame, and the speed as the egg rotation speed. In this way, the egg inherits the rotation of the cup and thus has the effect of revolution. It is worth noting that the COGs of virtual rigid body and cup are in the same projection point in the direction of rotation axis.