Thank you this was exactly what i needed. onsdag den 26. marts 2025 kl. 20.09.35 UTC+1 skrev Radu Serban:
> Hi Mathias, > > > > The most complete SMC model is implemented in the Chrono::Multicore > module. I never got around to bring up the corresponding SMC model in the > core Chrono module to the same level (although that is on one of the many > TODO lists I keep). > > Compared to the Chrono core implementation (see the implementation in > ChContactSMC.h > <https://github.com/projectchrono/chrono/blob/ca60083b2de78732f398adb895f1540ccfadd8b2/src/chrono/physics/ChContactSMC.h#L45>), > > the SMC contact model in Chrono::Multicore (see > ChIterativeSolverMulticoreSMC.cpp > <https://github.com/projectchrono/chrono/blob/ca60083b2de78732f398adb895f1540ccfadd8b2/src/chrono_multicore/solver/ChIterativeSolverMulticoreSMC.cpp#L56>) > > has the following two main additional features: > > - A multi-step tangential displacement model (see this paper > > <https://www.researchgate.net/publication/281538010_On_the_Importance_of_Displacement_History_in_Soft-Body_Contact_Models> > > for details on why that is important in SMC); and > - Rolling and spinning friction > > > > With the above, the kind of simulations you are interested in will give > the expect results. In fact, such behaviors are implemented and tested in a > series of tests that are included in the Chrono distribution: see the unit > tests for multicore SMC contact > <https://github.com/projectchrono/chrono/tree/main/src/tests/unit_tests/smc_contact/multicore> > . > > > > Having said all of that, please note that the Chrono::Multicore module is > currently **not** SWIG wrapped and as such not available through PyChrono. > > > > Best, > Radu > > > > > > *From:* [email protected] <[email protected]> *On > Behalf Of *mathias dalby larsen > *Sent:* Monday, March 24, 2025 10:12 AM > *To:* [email protected] > *Subject:* [chrono] Help with Rolling Friction Behavior in PyChrono SMC > Model > > > > Hello, > > I'm currently working on a PyChrono model using the SMC (Smooth Contact) > method to demonstrate how rolling friction behaves in simulations. The > setup I'm aiming to replicate is illustrated in the attached diagram, where > the goal is to observe different states of motion: stationary, pure > rolling, pure sliding, and combined rolling and sliding (as shown in the > second image). > > However, in my implementation, I am only able to achieve a combination of > rolling and sliding, when chaning the friction values. Additionally, even > with the wall set at a 0° incline and a friction coefficient of 0.25, the > sphere continues to roll indefinitely instead of coming to rest. > > Any guidance or insights into what might be wrong with my setup would be > greatly appreciated. > > PS.From my countless tests, it seems like the material data is only > applied during the first contact, however, I'm not quite sure. > > Best regards, > Mathias Dalby Larsen > > > > Code used > > import pychrono as chrono > > import pychrono.irrlicht as chronoirr > > import numpy as np > > > > # Simulation Parameters > > sphere_radius = 0.2 # meters > > sphere_mass = 5.0 # kg > > initial_velocity = 0.0 # m/s (parallel to incline, pointing up) > > incline_angle = 5 # degrees (fix the floor at this angle) > > static_friction = 0.25 # μs > > kinetic_friction = 0.25 # μk > > Rolling_friction = 0.50 # Rolling friction coefficient > > measure_time = 4.5 # Time after which velocities will be measured > > sim_time = 10 > > wall_depth = 15.0 # From wall dimensions > > > > # Convert incline angle to radians > > alpha_rad = np.radians(incline_angle) > > > > # Create system > > sys = chrono.ChSystemSMC() > > > > # Check the current normal contact force model > > print("Normal contact force before setting:", sys.GetContactForceModel()) > # Should return default value > > > > # Try setting it to Hooke > > #sys.SetContactForceModel(chrono.ChSystemSMC.Hooke) # Set Hooke model > explicitly > > # Try setting it to Hertz > > sys.SetContactForceModel(chrono.ChSystemSMC.Hertz) # Set Hertz model > explicitly > > # Try setting it to PlainCoulomb > > #sys.SetContactForceModel(chrono.ChSystemSMC.PlainCoulomb) # Set > PlainCoulomb model explicitly > > # Try setting it to Flores > > #sys.SetContactForceModel(chrono.ChSystemSMC.Flores) # Set Flores model > explicitly > > > > # Check if it changed > > print("Normal contact force after setting:", sys.GetContactForceModel()) > # Should print 1 (Hertz) > > > > # Check the current tangential contact force model > > print("Tangential contact force before setting:", > sys.GetTangentialDisplacementModel()) # Should return default value > > > > # Try setting it to None > > #sys.SetTangentialDisplacementModel(chrono.ChSystemSMC._None) # Set None > model explicitly > > # Try setting it to OneStep > > #sys.SetTangentialDisplacementModel(chrono.ChSystemSMC.OneStep) # Set > OneStep model explicitly > > # Try setting it to MultiStep > > sys.SetTangentialDisplacementModel(chrono.ChSystemSMC.MultiStep) # Set > MultiStep model explicitly > > > > # Check if it changed > > print("Tangential contact force after setting:", > sys.GetTangentialDisplacementModel()) # Should print 1 (Hertz) > > > > # Create Collision detection system and solver > > sys.SetCollisionSystemType(chrono.ChCollisionSystem.Type_BULLET) > > sys.SetSolverType(chrono.ChSolver.Type_BARZILAIBORWEIN) > > sys.GetSolver().AsIterative().SetMaxIterations(200) > > sys.UseMaterialProperties(True) > > > > # Set gravitational acceleration > > sys.SetGravitationalAcceleration(chrono.ChVector3d(0, -9.81, 0)) > > > > # Create a material for the inclined wall > > wall_mat = chrono.ChContactMaterialSMC() > > wall_mat.SetStaticFriction(static_friction) > > wall_mat.SetSlidingFriction(kinetic_friction) > > wall_mat.SetRollingFriction(Rolling_friction/2) > > wall_mat.SetRestitution(0.50) > > wall_mat.SetYoungModulus(1e9) > > wall_mat.SetPoissonRatio(0.3) > > wall_mat.SetSpinningFriction(Rolling_friction * 20.0) > > wall_mat.SetKn(1e9) > > wall_mat.SetKt(1e9) > > > > # Create the inclined wall (static floor) > > wall = chrono.ChBodyAuxRef() > > wall.SetFixed(True) > > wall.SetInertiaXX(chrono.ChVector3d(0.1, 0.1, 0.1)) > > wall.EnableCollision(True) > > > > # Apply correct rotation using `QuatFromAngleAxis` > > rotation_axis = chrono.ChVector3d(1, 0, 0) # Rotate around X-axis > > wall_rotation = chrono.QuatFromAngleAxis(-alpha_rad, rotation_axis) > > wall.SetRot(wall_rotation) > > > > # Position the wall correctly > > wall.SetPos(chrono.ChVector3d(0, 0, 0)) > > > > # Add collision shape > > wall_shape = chrono.ChCollisionShapeBox(wall_mat, 2, 0.1, wall_depth) > > wall.AddCollisionShape(wall_shape) > > > > # Add visual representation > > wall_vis = chrono.ChVisualShapeBox(2, 0.1, wall_depth) > > wall_vis.SetColor(chrono.ChColor(1, 0, 0)) # Red for visibility > > wall.AddVisualShape(wall_vis) > > > > # Add to system > > sys.Add(wall) > > > > # Create the rolling sphere > > sphere = chrono.ChBody() > > sphere.SetMass(sphere_mass) > > sphere.SetInertiaXX(chrono.ChVector3d(2/5 * sphere_mass * sphere_radius**2, > > 2/5 * sphere_mass * sphere_radius**2, > > 2/5 * sphere_mass * sphere_radius**2)) > > > > # Function to calculate the circle's center position > > def get_circle_position(radius, theta): > > y_c = -(radius+0.05) * np.sin(theta) > > z_c = (radius+0.05) * np.cos(theta) > > return y_c, z_c > > # Get the position of the circle center > > circle_pos = get_circle_position(sphere_radius, alpha_rad) > > sphere.SetPos(chrono.ChVector3d(0, circle_pos[1]+0.01, circle_pos[0]+0.01)) > > > > # Set initial velocity along the incline > > sphere.SetPosDt(chrono.ChVector3d(0,initial_velocity * np.sin(alpha_rad), > > initial_velocity * np.cos(alpha_rad))) > > > > # Add sphere collision and visualization > > sphere_mat = chrono.ChContactMaterialSMC() > > sphere_mat.SetStaticFriction(static_friction) > > sphere_mat.SetSlidingFriction(kinetic_friction) > > sphere_mat.SetRollingFriction(Rolling_friction/2) > > sphere_mat.SetRestitution(0.50) > > sphere_mat.SetYoungModulus(1e9) > > sphere_mat.SetPoissonRatio(0.3) > > sphere_mat.SetSpinningFriction(Rolling_friction * 20.0) > > sphere_mat.SetKn(1e9) > > sphere_mat.SetKt(1e9) > > > > # Assign material directly to the body > > sphere_shape = chrono.ChCollisionShapeSphere(sphere_mat, sphere_radius) > > sphere.AddCollisionShape(sphere_shape) > > sphere.EnableCollision(True) > > > > sphere_vis = chrono.ChVisualShapeSphere(sphere_radius) > > sphere_vis.SetColor(chrono.ChColor(1, 1, 0)) # Yellow sphere > > sphere.AddVisualShape(sphere_vis) > > > > # Add sphere to system > > sys.Add(sphere) > > > > # Set up the Irrlicht visualization > > vis = chronoirr.ChVisualSystemIrrlicht() > > vis.AttachSystem(sys) > > vis.SetWindowSize(1024, 768) > > vis.SetWindowTitle('Rolling Ball on Inclined Wall') > > vis.Initialize() > > vis.AddSkyBox() > > vis.AddCamera(chrono.ChVector3d(-2, 0, -0.5), chrono.ChVector3d(0, 0, 0)) > > vis.AddTypicalLights() > > > > # Simulation loop > > time = 0.0 > > dt = 10e-6 # Keep accurate physics time step > > render_interval = 1000 # Render every 10th step for 10x faster visual > effect > > step_count = 0 > > realtime_timer = chrono.ChRealtimeStepTimer() > > lin_vel = None > > > > while vis.Run(): > > if step_count % render_interval == 0: # Render only every 10th step > > vis.BeginScene() > > vis.Render() > > vis.EndScene() > > > > # Advance simulation > > sys.DoStepDynamics(dt) > > time += dt > > step_count += 1 > > > > # Adjust real-time sync for 10x faster visualization > > if step_count % render_interval == 0: > > realtime_timer.Spin(dt * render_interval) > > > > # Measure velocities at exactly measure_time > > if time >= measure_time and lin_vel is None: # Only measure once > > lin_vel = sphere.GetLinVel().Length() > > ang_acc = sphere.GetAngVelLocal().Length() # Angular acceleration > magnitude > > Rollslide = abs((sphere_radius * ang_acc)) > > print(f"Measured at {measure_time}s -> Lin Vel: {lin_vel}, Rot > Change: {ang_acc}, Rot rollslide: {Rollslide}") > > force = sphere.GetContactForce() > > torque = sphere.GetContactTorque() > > print(f"Time: {time:.3f} - Contact Force: {force.Length()}, > Contact Torque: {torque.Length()}") > > > > > > -- > > You received this message because you are subscribed to the Google Groups > "ProjectChrono" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion visit > https://groups.google.com/d/msgid/projectchrono/SA1P220MB1275A64A7BE884B285864FFDAEA42%40SA1P220MB1275.NAMP220.PROD.OUTLOOK.COM > > <https://urldefense.com/v3/__https:/groups.google.com/d/msgid/projectchrono/SA1P220MB1275A64A7BE884B285864FFDAEA42*40SA1P220MB1275.NAMP220.PROD.OUTLOOK.COM?utm_medium=email&utm_source=footer__;JQ!!Mak6IKo!IBQgS7fUmMwUVLU_nkkK6qZGuHR5easzklZgtkSA9NDWNMtz9r7RJ4VlvVWz7UrhEy-iiRS-1wtwgxUv7-hPT1GkFA$> > . > -- You received this message because you are subscribed to the Google Groups "ProjectChrono" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/projectchrono/64c9dcfe-60fc-4959-82c6-16cb6e9d92a3n%40googlegroups.com.
