├── .gitignore ├── Chrono ├── wheeled_vehicle │ ├── data │ │ ├── terrain │ │ │ ├── tile4.jpg │ │ │ └── RigidPlane.json │ │ └── vehicle │ │ │ ├── BrakeSimple.json │ │ │ ├── EngineSimple.json │ │ │ ├── BrakeShafts.json │ │ │ ├── Wheel.json │ │ │ ├── RackPinion.json │ │ │ ├── AutomaticTransmissionSimpleMap.json │ │ │ ├── Chassis.json │ │ │ ├── EngineSimpleMap.json │ │ │ ├── Driveline4WD.json │ │ │ ├── RigidTire.json │ │ │ ├── EngineShafts.json │ │ │ ├── AutomaticTransmissionShafts.json │ │ │ ├── TMeasyTire.json │ │ │ ├── WheeledVehicle.json │ │ │ ├── PitmanArm.json │ │ │ ├── MultiLink.json │ │ │ └── DoubleWishbone.json │ ├── solution │ │ ├── WheeledVehicle_mod.json │ │ ├── DoubleWishboneReduced.json │ │ └── SolidAxle.json │ ├── CMakeLists.txt │ └── wheeled_vehicle.cpp ├── README.md ├── slider_crank │ ├── CMakeLists.txt │ ├── slider_crank_0.cpp │ ├── slider_crank_1.cpp │ └── slider_crank_1_solution.cpp ├── multicore │ ├── CMakeLists.txt │ ├── cratering.cpp │ ├── cratering_solution_1.cpp │ └── cratering_solution_2.cpp ├── FEA │ ├── CMakeLists.txt │ └── FEA_cable_collide_2.cpp ├── sensor │ └── CMakeLists.txt └── synchrono │ └── CMakeLists.txt ├── PyChrono ├── wheeled_vehicle │ ├── data │ │ ├── terrain │ │ │ ├── tile4.jpg │ │ │ └── RigidPlane.json │ │ └── vehicle │ │ │ ├── BrakeSimple.json │ │ │ ├── EngineSimple.json │ │ │ ├── BrakeShafts.json │ │ │ ├── Wheel.json │ │ │ ├── RackPinion.json │ │ │ ├── AutomaticTransmissionSimpleMap.json │ │ │ ├── Chassis.json │ │ │ ├── Driveline4WD.json │ │ │ ├── EngineSimpleMap.json │ │ │ ├── RigidTire.json │ │ │ ├── EngineShafts.json │ │ │ ├── AutomaticTransmissionShafts.json │ │ │ ├── TMeasyTire.json │ │ │ ├── WheeledVehicle.json │ │ │ ├── PitmanArm.json │ │ │ ├── MultiLink.json │ │ │ └── DoubleWishbone.json │ ├── solution │ │ ├── WheeledVehicle_mod.json │ │ ├── DoubleWishboneReduced.json │ │ └── SolidAxle.json │ └── wheeled_vehicle.py ├── README.md ├── slider-crank │ ├── slider_crank_0.py │ ├── slider_crank_1.py │ ├── slider_crank_1_solution.py │ └── slider_crank_2.py └── FEA │ ├── FEA_cable_collide_2.py │ ├── FEA_cable_collide_1.py │ └── FEA_cable_collide_1_solution.py ├── README.md ├── .clang-format └── CMakeLists.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/* 2 | /build* -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/terrain/tile4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projectchrono/chrono-tutorial/HEAD/Chrono/wheeled_vehicle/data/terrain/tile4.jpg -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/terrain/tile4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/projectchrono/chrono-tutorial/HEAD/PyChrono/wheeled_vehicle/data/terrain/tile4.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Chrono tutorials 2 | ================ 3 | 4 | - Chrono/: C++ tutorials for various Chrono modules 5 | - PyChrono/: Python tutorials for various Chrono modules 6 | 7 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Chromium 2 | 3 | # Longer lines 4 | ColumnLimit: 120 5 | 6 | # Increase indentation 7 | IndentWidth: 4 8 | TabWidth: 4 9 | AccessModifierOffset: -2 10 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/BrakeSimple.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Simple Brake", 3 | "Type": "Brake", 4 | "Template": "BrakeSimple", 5 | 6 | "Maximum Torque": 4000 7 | } 8 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/BrakeSimple.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Simple Brake", 3 | "Type": "Brake", 4 | "Template": "BrakeSimple", 5 | 6 | "Maximum Torque": 4000 7 | } 8 | -------------------------------------------------------------------------------- /PyChrono/README.md: -------------------------------------------------------------------------------- 1 | PyChrono tutorials 2 | ================== 3 | 4 | - slider_crank: basic usage of the Chrono core module for MBD 5 | - FEA: basic usage of the Chrono core module for FEA 6 | - wheeled_vehicle: tutorial for vehicle dynamics using JSON-based specification 7 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/EngineSimple.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Simple Engine", 3 | "Type": "Engine", 4 | "Template": "EngineSimple", 5 | 6 | "Maximum Engine Torque": 330, 7 | "Maximum Engine Power": 110000, 8 | "Maximum Engine Speed": 10000 9 | } 10 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/EngineSimple.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Simple Engine", 3 | "Type": "Engine", 4 | "Template": "EngineSimple", 5 | 6 | "Maximum Engine Torque": 330, 7 | "Maximum Engine Power": 110000, 8 | "Maximum Engine Speed": 10000 9 | } 10 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/BrakeShafts.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Shafts Brake", 3 | "Type": "Brake", 4 | "Template": "BrakeShafts", 5 | 6 | "Shaft Inertia": 0.4, 7 | "Maximum Torque": 4000 8 | } 9 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/BrakeShafts.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Shafts Brake", 3 | "Type": "Brake", 4 | "Template": "BrakeShafts", 5 | 6 | "Shaft Inertia": 0.4, 7 | "Maximum Torque": 4000 8 | } 9 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/Wheel.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Wheel", 3 | "Type": "Wheel", 4 | "Template": "Wheel", 5 | 6 | "Mass": 18.8, 7 | "Inertia": [0.4634, 0.6243, 0.4634], 8 | 9 | "Visualization": { 10 | "Radius": 0.268, 11 | "Width": 0.22 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/Wheel.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Wheel", 3 | "Type": "Wheel", 4 | "Template": "Wheel", 5 | 6 | "Mass": 18.8, 7 | "Inertia": [0.4634, 0.6243, 0.4634], 8 | 9 | "Visualization": { 10 | "Radius": 0.268, 11 | "Width": 0.22 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chrono/README.md: -------------------------------------------------------------------------------- 1 | Chrono C++ tutorials 2 | ==================== 3 | 4 | - slider_crank: basic usage of the Chrono core module for MBD 5 | - FEA: basic usage of the Chrono core module for FEA 6 | - multicore: DEM with the Chrono::Multicore module 7 | - wheeled_vehicle: tutorial for vehicle dynamics using JSON-based specification 8 | - sensor: use of camera and lidar sensors with a ground vehicle 9 | - synchrono: tutorial for using Synchrono for a distributed vehicle simulation 10 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/RackPinion.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Rack-Pinion Steering", 3 | "Type": "Steering", 4 | "Template": "RackPinion", 5 | 6 | "Steering Link": 7 | { 8 | "Mass": 9.072, 9 | "COM": 0, 10 | "Inertia": [1, 1, 1], 11 | "Radius": 0.03, 12 | "Length": 0.896 13 | }, 14 | 15 | "Pinion": 16 | { 17 | "Radius": 0.1, 18 | "Maximum Angle (deg)": 50 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/RackPinion.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Rack-Pinion Steering", 3 | "Type": "Steering", 4 | "Template": "RackPinion", 5 | 6 | "Steering Link": 7 | { 8 | "Mass": 9.072, 9 | "COM": 0, 10 | "Inertia": [1, 1, 1], 11 | "Radius": 0.03, 12 | "Length": 0.896 13 | }, 14 | 15 | "Pinion": 16 | { 17 | "Radius": 0.1, 18 | "Maximum Angle (deg)": 50 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/AutomaticTransmissionSimpleMap.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Simple Map Transmission", 3 | "Type": "Transmission", 4 | "Template": "AutomaticTransmissionSimpleMap", 5 | 6 | "Gear Box": { 7 | "Reverse Gear Ratio": -0.151, 8 | "Forward Gear Ratios": [ 9 | 0.1708, 10 | 0.2791, 11 | 0.4218, 12 | 0.6223, 13 | 1.0173, 14 | 1.5361 15 | ], 16 | "Shift Points Map RPM": [ 17 | [ 1000, 2226 ], 18 | [ 1000, 2225 ], 19 | [ 1000, 2210 ], 20 | [ 1000, 2226 ], 21 | [ 1000, 2225 ], 22 | [ 1000, 2700 ] 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/AutomaticTransmissionSimpleMap.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Simple Map Transmission", 3 | "Type": "Transmission", 4 | "Template": "AutomaticTransmissionSimpleMap", 5 | 6 | "Gear Box": { 7 | "Reverse Gear Ratio": -0.151, 8 | "Forward Gear Ratios": [ 9 | 0.1708, 10 | 0.2791, 11 | 0.4218, 12 | 0.6223, 13 | 1.0173, 14 | 1.5361 15 | ], 16 | "Shift Points Map RPM": [ 17 | [ 1000, 2226 ], 18 | [ 1000, 2225 ], 19 | [ 1000, 2210 ], 20 | [ 1000, 2226 ], 21 | [ 1000, 2225 ], 22 | [ 1000, 2700 ] 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/Chassis.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Vehicle Chassis", 3 | "Type": "Chassis", 4 | "Template": "RigidChassis", 5 | 6 | "Components": 7 | [ 8 | { 9 | "Centroidal Frame": { 10 | "Location": [0.056, 0, 0.213], 11 | "Orientation": [1, 0, 0, 0] 12 | }, 13 | "Mass": 2086.52, 14 | "Moments of Inertia": [1078.52, 2955.66, 3570.20], 15 | "Products of Inertia": [0, 0, 0], 16 | "Void": false 17 | } 18 | ], 19 | 20 | "Driver Position": 21 | { 22 | "Location": [0.87, 0.7, 1.05], 23 | "Orientation": [1, 0, 0, 0] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/Chassis.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Vehicle Chassis", 3 | "Type": "Chassis", 4 | "Template": "RigidChassis", 5 | 6 | "Components": 7 | [ 8 | { 9 | "Centroidal Frame": { 10 | "Location": [0.056, 0, 0.213], 11 | "Orientation": [1, 0, 0, 0] 12 | }, 13 | "Mass": 2086.52, 14 | "Moments of Inertia": [1078.52, 2955.66, 3570.20], 15 | "Products of Inertia": [0, 0, 0], 16 | "Void": false 17 | } 18 | ], 19 | 20 | "Driver Position": 21 | { 22 | "Location": [0.87, 0.7, 1.05], 23 | "Orientation": [1, 0, 0, 0] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/EngineSimpleMap.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Simple Map Engine", 3 | "Type": "Engine", 4 | "Template": "EngineSimpleMap", 5 | 6 | "Maximal Engine Speed RPM": 2600, 7 | "Map Full Throttle": [ 8 | [ -100, 300 ], 9 | [ 800, 382 ], 10 | [ 900, 490 ], 11 | [ 1000, 579 ], 12 | [ 1100, 650 ], 13 | [ 1200, 706 ], 14 | [ 1300, 746 ], 15 | [ 1400, 774 ], 16 | [ 1500, 789 ], 17 | [ 1600, 793 ], 18 | [ 1700, 788 ], 19 | [ 1800, 774 ], 20 | [ 1900, 754 ], 21 | [ 2000, 728 ], 22 | [ 2100, 697 ], 23 | [ 2200, 664 ], 24 | [ 2300, 628 ], 25 | [ 2400, 593 ], 26 | [ 2500, 558 ], 27 | [ 2700, -400 ] 28 | ], 29 | "Map Zero Throttle": [ 30 | [ -100, 0 ], 31 | [ 0, 0 ], 32 | [ 100, 0 ], 33 | [ 1000, -50 ], 34 | [ 2000, -70 ], 35 | [ 3000, -90 ] 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/Driveline4WD.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "4WD Driveline", 3 | "Type": "Driveline", 4 | "Template": "ShaftsDriveline4WD", 5 | 6 | "Shaft Direction": 7 | { 8 | "Motor Block": [1, 0, 0], 9 | "Axle": [0, 1, 0] 10 | }, 11 | 12 | "Shaft Inertia": 13 | { 14 | "Driveshaft": 0.5, 15 | "Front Driveshaft": 0.5, 16 | "Rear Driveshaft": 0.5, 17 | "Central Differential Box": 0.6, 18 | "Front Differential Box": 0.6, 19 | "Rear Differential Box": 0.6 20 | }, 21 | 22 | "Gear Ratio": 23 | { 24 | "Front Conical Gear": 0.2, 25 | "Rear Conical Gear": 0.2 26 | }, 27 | 28 | "Axle Differential Locking Limit": 100, 29 | "Central Differential Locking Limit": 100 30 | } 31 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/Driveline4WD.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "4WD Driveline", 3 | "Type": "Driveline", 4 | "Template": "ShaftsDriveline4WD", 5 | 6 | "Shaft Direction": 7 | { 8 | "Motor Block": [1, 0, 0], 9 | "Axle": [0, 1, 0] 10 | }, 11 | 12 | "Shaft Inertia": 13 | { 14 | "Driveshaft": 0.5, 15 | "Front Driveshaft": 0.5, 16 | "Rear Driveshaft": 0.5, 17 | "Central Differential Box": 0.6, 18 | "Front Differential Box": 0.6, 19 | "Rear Differential Box": 0.6 20 | }, 21 | 22 | "Gear Ratio": 23 | { 24 | "Front Conical Gear": 0.2, 25 | "Rear Conical Gear": 0.2 26 | }, 27 | 28 | "Axle Differential Locking Limit": 100, 29 | "Central Differential Locking Limit": 100 30 | } 31 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/EngineSimpleMap.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Simple Map Engine", 3 | "Type": "Engine", 4 | "Template": "EngineSimpleMap", 5 | 6 | "Maximal Engine Speed RPM": 2600, 7 | "Map Full Throttle": [ 8 | [ -100, 300 ], 9 | [ 800, 382 ], 10 | [ 900, 490 ], 11 | [ 1000, 579 ], 12 | [ 1100, 650 ], 13 | [ 1200, 706 ], 14 | [ 1300, 746 ], 15 | [ 1400, 774 ], 16 | [ 1500, 789 ], 17 | [ 1600, 793 ], 18 | [ 1700, 788 ], 19 | [ 1800, 774 ], 20 | [ 1900, 754 ], 21 | [ 2000, 728 ], 22 | [ 2100, 697 ], 23 | [ 2200, 664 ], 24 | [ 2300, 628 ], 25 | [ 2400, 593 ], 26 | [ 2500, 558 ], 27 | [ 2700, -400 ] 28 | ], 29 | "Map Zero Throttle": [ 30 | [ -100, 0 ], 31 | [ 0, 0 ], 32 | [ 100, 0 ], 33 | [ 1000, -50 ], 34 | [ 2000, -70 ], 35 | [ 3000, -90 ] 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/RigidTire.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Rigid Tire", 3 | "Type": "Tire", 4 | "Template": "RigidTire", 5 | 6 | "Radius": 0.467, 7 | "Width": 0.254, 8 | "Mass": 37.6, 9 | "Inertia": [3.84, 6.69, 3.84], 10 | 11 | "Contact Material": 12 | { 13 | "Coefficient of Friction": 0.9, 14 | "Coefficient of Restitution": 0.1, 15 | 16 | "Properties": { 17 | "Young Modulus": 2e7, 18 | "Poisson Ratio": 0.3 19 | }, 20 | 21 | "Coefficients": { 22 | "Normal Stiffness": 2e5, 23 | "Normal Damping": 40.0, 24 | "Tangential Stiffness": 2e5, 25 | "Tangential Damping": 20.0 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/RigidTire.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Rigid Tire", 3 | "Type": "Tire", 4 | "Template": "RigidTire", 5 | 6 | "Radius": 0.467, 7 | "Width": 0.254, 8 | "Mass": 37.6, 9 | "Inertia": [3.84, 6.69, 3.84], 10 | 11 | "Contact Material": 12 | { 13 | "Coefficient of Friction": 0.9, 14 | "Coefficient of Restitution": 0.1, 15 | 16 | "Properties": { 17 | "Young Modulus": 2e7, 18 | "Poisson Ratio": 0.3 19 | }, 20 | 21 | "Coefficients": { 22 | "Normal Stiffness": 2e5, 23 | "Normal Damping": 40.0, 24 | "Tangential Stiffness": 2e5, 25 | "Tangential Damping": 20.0 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/EngineShafts.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Shafts Engine", 3 | "Type": "Engine", 4 | "Template": "EngineShafts", 5 | 6 | "Motor Block Inertia": 10.5, // connection to chassis 7 | "Motorshaft Inertia": 1.1, // connection to transmission 8 | 9 | "Torque Map": [ 10 | [ -100, 300 ], 11 | [ 800, 382 ], 12 | [ 900, 490 ], 13 | [ 1000, 579 ], 14 | [ 1100, 650 ], 15 | [ 1200, 706 ], 16 | [ 1300, 746 ], 17 | [ 1400, 774 ], 18 | [ 1500, 789 ], 19 | [ 1600, 793 ], 20 | [ 1700, 788 ], 21 | [ 1800, 774 ], 22 | [ 1900, 754 ], 23 | [ 2000, 728 ], 24 | [ 2100, 697 ], 25 | [ 2200, 664 ], 26 | [ 2300, 628 ], 27 | [ 2400, 593 ], 28 | [ 2500, 558 ], 29 | [ 2700, -400 ] 30 | ], 31 | 32 | "Losses Map": [ 33 | [ -50, 30 ], 34 | [ 0, 0 ], 35 | [ 50, -30 ], 36 | [ 1000, -50 ], 37 | [ 2000, -70 ], 38 | [ 3000, -90 ] 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/EngineShafts.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Shafts Engine", 3 | "Type": "Engine", 4 | "Template": "EngineShafts", 5 | 6 | "Motor Block Inertia": 10.5, // connection to chassis 7 | "Motorshaft Inertia": 1.1, // connection to transmission 8 | 9 | "Torque Map": [ 10 | [ -100, 300 ], 11 | [ 800, 382 ], 12 | [ 900, 490 ], 13 | [ 1000, 579 ], 14 | [ 1100, 650 ], 15 | [ 1200, 706 ], 16 | [ 1300, 746 ], 17 | [ 1400, 774 ], 18 | [ 1500, 789 ], 19 | [ 1600, 793 ], 20 | [ 1700, 788 ], 21 | [ 1800, 774 ], 22 | [ 1900, 754 ], 23 | [ 2000, 728 ], 24 | [ 2100, 697 ], 25 | [ 2200, 664 ], 26 | [ 2300, 628 ], 27 | [ 2400, 593 ], 28 | [ 2500, 558 ], 29 | [ 2700, -400 ] 30 | ], 31 | 32 | "Losses Map": [ 33 | [ -50, 30 ], 34 | [ 0, 0 ], 35 | [ 50, -30 ], 36 | [ 1000, -50 ], 37 | [ 2000, -70 ], 38 | [ 3000, -90 ] 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/terrain/RigidPlane.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Rigid plane", 3 | "Type": "Terrain", 4 | "Template": "RigidTerrain", 5 | 6 | "Patches": [ 7 | { 8 | "Location": [ 0, 0, 0 ], 9 | "Orientation": [ 1, 0, 0, 0 ], 10 | 11 | "Geometry": { 12 | "Dimensions": [ 300, 300, 2 ] 13 | }, 14 | 15 | "Contact Material": { 16 | "Coefficient of Friction": 0.9, 17 | "Coefficient of Restitution": 0.01, 18 | "Properties": { 19 | "Young Modulus": 2e7, 20 | "Poisson Ratio": 0.3 21 | }, 22 | "Coefficients": { 23 | "Normal Stiffness": 2e5, 24 | "Normal Damping": 40.0, 25 | "Tangential Stiffness": 2e5, 26 | "Tangential Damping": 20.0 27 | } 28 | }, 29 | 30 | "Visualization": { 31 | "Color": [ 0.5, 0.5, 0.8 ], 32 | "Texture File": "terrain/tile4.jpg", 33 | "Texture Scaling": [ 200, 200 ] 34 | } 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/terrain/RigidPlane.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Rigid plane", 3 | "Type": "Terrain", 4 | "Template": "RigidTerrain", 5 | 6 | "Patches": [ 7 | { 8 | "Location": [ 0, 0, 0 ], 9 | "Orientation": [ 1, 0, 0, 0 ], 10 | 11 | "Geometry": { 12 | "Dimensions": [ 300, 300, 2 ] 13 | }, 14 | 15 | "Contact Material": { 16 | "Coefficient of Friction": 0.9, 17 | "Coefficient of Restitution": 0.01, 18 | "Properties": { 19 | "Young Modulus": 2e7, 20 | "Poisson Ratio": 0.3 21 | }, 22 | "Coefficients": { 23 | "Normal Stiffness": 2e5, 24 | "Normal Damping": 40.0, 25 | "Tangential Stiffness": 2e5, 26 | "Tangential Damping": 20.0 27 | } 28 | }, 29 | 30 | "Visualization": { 31 | "Color": [ 0.5, 0.5, 0.8 ], 32 | "Texture File": "terrain/tile4.jpg", 33 | "Texture Scaling": [ 200, 200 ] 34 | } 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/AutomaticTransmissionShafts.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Shafts Automatic Transmission", 3 | "Type": "Transmission", 4 | "Template": "AutomaticTransmissionShafts", 5 | 6 | "Transmission Block Inertia": 10.5, // connection to chassis 7 | "Input Shaft Inertia": 0.3, 8 | "Motorshaft Inertia": 0.5, // connection to engine 9 | "Driveshaft Inertia": 0.5, // connection to driveline 10 | 11 | "Torque Converter": { 12 | "Capacity Factor Map": [ 13 | [ 0.00, 15.00 ], 14 | [ 0.25, 15.00 ], 15 | [ 0.50, 15.00 ], 16 | [ 0.75, 16.00 ], 17 | [ 0.90, 18.00 ], 18 | [ 1.00, 35.00 ] 19 | ], 20 | "Torque Ratio Map": [ 21 | [ 0.00, 2.00 ], 22 | [ 0.25, 1.80 ], 23 | [ 0.50, 1.50 ], 24 | [ 0.75, 1.15 ], 25 | [ 1.00, 1.00 ] 26 | ] 27 | }, 28 | 29 | "Gear Box": { 30 | "Forward Gear Ratios": [ 0.2, 0.4, 0.8 ], 31 | "Reverse Gear Ratio": -0.1, 32 | "Upshift RPM": 2500, 33 | "Downshift RPM": 1200, 34 | "Shift Latency": 1.0 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/AutomaticTransmissionShafts.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Shafts Automatic Transmission", 3 | "Type": "Transmission", 4 | "Template": "AutomaticTransmissionShafts", 5 | 6 | "Transmission Block Inertia": 10.5, // connection to chassis 7 | "Input Shaft Inertia": 0.3, 8 | "Motorshaft Inertia": 0.5, // connection to engine 9 | "Driveshaft Inertia": 0.5, // connection to driveline 10 | 11 | "Torque Converter": { 12 | "Capacity Factor Map": [ 13 | [ 0.00, 15.00 ], 14 | [ 0.25, 15.00 ], 15 | [ 0.50, 15.00 ], 16 | [ 0.75, 16.00 ], 17 | [ 0.90, 18.00 ], 18 | [ 1.00, 35.00 ] 19 | ], 20 | "Torque Ratio Map": [ 21 | [ 0.00, 2.00 ], 22 | [ 0.25, 1.80 ], 23 | [ 0.50, 1.50 ], 24 | [ 0.75, 1.15 ], 25 | [ 1.00, 1.00 ] 26 | ] 27 | }, 28 | 29 | "Gear Box": { 30 | "Forward Gear Ratios": [ 0.2, 0.4, 0.8 ], 31 | "Reverse Gear Ratio": -0.1, 32 | "Upshift RPM": 2500, 33 | "Downshift RPM": 1200, 34 | "Shift Latency": 1.0 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/TMeasyTire.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "TMeasy Tire", 3 | "Type": "Tire", 4 | "Template": "TMeasyTire", 5 | 6 | // ------------------------------------------------ 7 | // Tire design (REQUIRED) 8 | 9 | "Design": { 10 | "Unloaded Radius [m]": 0.4699, 11 | "Mass [kg]": 37.6, 12 | "Inertia [kg.m2]": [ 3.84, 6.69, 3.84 ], 13 | "Width [m]": 0.3175, 14 | "Rim Radius [m]": 0.2095 15 | }, 16 | 17 | "Coefficient of Friction": 0.8, 18 | 19 | "Rolling Resistance Coefficients": [ 0.015, 0.015 ], 20 | 21 | // ------------------------------------------------ 22 | // Vehicle type. 23 | // Required only if tire specified with "load index" or "bearing capacity". 24 | // Must be one of "Truck" or "Passenger" 25 | 26 | "Vehicle Type": "Truck", 27 | 28 | // ------------------------------------------------ 29 | // Load index specification. 30 | // Takes priority over "bearing capacity" (used only if a full parameterization not provided) 31 | 32 | "Load Index": 108, 33 | 34 | // ------------------------------------------------ 35 | // Bearing capacity specification. 36 | // Lowest priority (used only if no other specification provided) 37 | 38 | "Maximum Bearing Capacity [N]": 17167.5 39 | 40 | } 41 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/TMeasyTire.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "TMeasy Tire", 3 | "Type": "Tire", 4 | "Template": "TMeasyTire", 5 | 6 | // ------------------------------------------------ 7 | // Tire design (REQUIRED) 8 | 9 | "Design": { 10 | "Unloaded Radius [m]": 0.4699, 11 | "Mass [kg]": 37.6, 12 | "Inertia [kg.m2]": [ 3.84, 6.69, 3.84 ], 13 | "Width [m]": 0.3175, 14 | "Rim Radius [m]": 0.2095 15 | }, 16 | 17 | "Coefficient of Friction": 0.8, 18 | 19 | "Rolling Resistance Coefficients": [ 0.015, 0.015 ], 20 | 21 | // ------------------------------------------------ 22 | // Vehicle type. 23 | // Required only if tire specified with "load index" or "bearing capacity". 24 | // Must be one of "Truck" or "Passenger" 25 | 26 | "Vehicle Type": "Truck", 27 | 28 | // ------------------------------------------------ 29 | // Load index specification. 30 | // Takes priority over "bearing capacity" (used only if a full parameterization not provided) 31 | 32 | "Load Index": 108, 33 | 34 | // ------------------------------------------------ 35 | // Bearing capacity specification. 36 | // Lowest priority (used only if no other specification provided) 37 | 38 | "Maximum Bearing Capacity [N]": 17167.5 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/solution/WheeledVehicle_mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Test vehicle - Double Wishbone", 3 | "Type": "Vehicle", 4 | "Template": "WheeledVehicle", 5 | 6 | "Chassis": 7 | { 8 | "Input File": "vehicle/Chassis.json" 9 | }, 10 | 11 | "Axles": 12 | [ 13 | { 14 | "Suspension Input File": "vehicle/DoubleWishboneReduced.json", 15 | "Suspension Location": [1.25, 0, -0.21], 16 | "Steering Index": 0, 17 | "Left Wheel Input File": "vehicle/Wheel.json", 18 | "Right Wheel Input File": "vehicle/Wheel.json", 19 | "Left Brake Input File": "vehicle/Brake.json", 20 | "Right Brake Input File": "vehicle/Brake.json" 21 | }, 22 | 23 | { 24 | "Suspension Input File": "vehicle/SolidAxle.json", 25 | "Suspension Location": [-1.25, 0, -0.21], 26 | "Left Wheel Input File": "vehicle/Wheel.json", 27 | "Right Wheel Input File": "vehicle/Wheel.json", 28 | "Left Brake Input File": "vehicle/Brake.json", 29 | "Right Brake Input File": "vehicle/Brake.json" 30 | } 31 | ], 32 | 33 | "Steering Subsystems": 34 | [ 35 | { 36 | "Input File": "vehicle/PitmanArm.json", 37 | "Location": [1.1, 0, -0.4], 38 | "Orientation": [0.98699637, 0, 0.16074256, 0] 39 | } 40 | ], 41 | 42 | "Driveline": 43 | { 44 | "Input File": "vehicle/Driveline4WD.json", 45 | "Suspension Indexes": [0, 1] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/solution/WheeledVehicle_mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Test vehicle - Double Wishbone", 3 | "Type": "Vehicle", 4 | "Template": "WheeledVehicle", 5 | 6 | "Chassis": 7 | { 8 | "Input File": "vehicle/Chassis.json" 9 | }, 10 | 11 | "Axles": 12 | [ 13 | { 14 | "Suspension Input File": "vehicle/DoubleWishboneReduced.json", 15 | "Suspension Location": [1.25, 0, -0.21], 16 | "Steering Index": 0, 17 | "Left Wheel Input File": "vehicle/Wheel.json", 18 | "Right Wheel Input File": "vehicle/Wheel.json", 19 | "Left Brake Input File": "vehicle/Brake.json", 20 | "Right Brake Input File": "vehicle/Brake.json" 21 | }, 22 | 23 | { 24 | "Suspension Input File": "vehicle/SolidAxle.json", 25 | "Suspension Location": [-1.25, 0, -0.21], 26 | "Left Wheel Input File": "vehicle/Wheel.json", 27 | "Right Wheel Input File": "vehicle/Wheel.json", 28 | "Left Brake Input File": "vehicle/Brake.json", 29 | "Right Brake Input File": "vehicle/Brake.json" 30 | } 31 | ], 32 | 33 | "Steering Subsystems": 34 | [ 35 | { 36 | "Input File": "vehicle/PitmanArm.json", 37 | "Location": [1.1, 0, -0.4], 38 | "Orientation": [0.98699637, 0, 0.16074256, 0] 39 | } 40 | ], 41 | 42 | "Driveline": 43 | { 44 | "Input File": "vehicle/Driveline4WD.json", 45 | "Suspension Indexes": [0, 1] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/WheeledVehicle.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Test vehicle", 3 | "Type": "Vehicle", 4 | "Template": "WheeledVehicle", 5 | 6 | "Chassis": { 7 | "Input File": "vehicle/Chassis.json" 8 | }, 9 | 10 | "Axles": [ 11 | { 12 | "Suspension Input File": "vehicle/DoubleWishbone.json", 13 | "Suspension Location": [ 1.688965, 0, 0 ], 14 | "Steering Index": 0, 15 | "Left Wheel Input File": "vehicle/Wheel.json", 16 | "Right Wheel Input File": "vehicle/Wheel.json", 17 | "Left Brake Input File": "vehicle/BrakeSimple.json", 18 | "Right Brake Input File": "vehicle/BrakeSimple.json" 19 | }, 20 | 21 | { 22 | "Suspension Input File": "vehicle/DoubleWishbone.json", 23 | "Suspension Location": [ -1.688965, 0, 0 ], 24 | "Left Wheel Input File": "vehicle/Wheel.json", 25 | "Right Wheel Input File": "vehicle/Wheel.json", 26 | "Left Brake Input File": "vehicle/BrakeSimple.json", 27 | "Right Brake Input File": "vehicle/BrakeSimple.json" 28 | } 29 | ], 30 | 31 | "Steering Subsystems": [ 32 | { 33 | "Input File": "vehicle/PitmanArm.json", 34 | "Location": [ 1.24498, 0, 0.101322 ], 35 | "Orientation": [ 0.98699637, 0, 0.16074256, 0 ] 36 | } 37 | ], 38 | 39 | "Wheelbase": 3.378, 40 | "Minimum Turning Radius": 7.62, 41 | "Maximum Steering Angle (deg)": 30.23, 42 | 43 | "Driveline": { 44 | "Input File": "vehicle/Driveline4WD.json", 45 | "Suspension Indexes": [ 0, 1 ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/WheeledVehicle.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Test vehicle", 3 | "Type": "Vehicle", 4 | "Template": "WheeledVehicle", 5 | 6 | "Chassis": { 7 | "Input File": "vehicle/Chassis.json" 8 | }, 9 | 10 | "Axles": [ 11 | { 12 | "Suspension Input File": "vehicle/DoubleWishbone.json", 13 | "Suspension Location": [ 1.688965, 0, 0 ], 14 | "Steering Index": 0, 15 | "Left Wheel Input File": "vehicle/Wheel.json", 16 | "Right Wheel Input File": "vehicle/Wheel.json", 17 | "Left Brake Input File": "vehicle/BrakeSimple.json", 18 | "Right Brake Input File": "vehicle/BrakeSimple.json" 19 | }, 20 | 21 | { 22 | "Suspension Input File": "vehicle/DoubleWishbone.json", 23 | "Suspension Location": [ -1.688965, 0, 0 ], 24 | "Left Wheel Input File": "vehicle/Wheel.json", 25 | "Right Wheel Input File": "vehicle/Wheel.json", 26 | "Left Brake Input File": "vehicle/BrakeSimple.json", 27 | "Right Brake Input File": "vehicle/BrakeSimple.json" 28 | } 29 | ], 30 | 31 | "Steering Subsystems": [ 32 | { 33 | "Input File": "vehicle/PitmanArm.json", 34 | "Location": [ 1.24498, 0, 0.101322 ], 35 | "Orientation": [ 0.98699637, 0, 0.16074256, 0 ] 36 | } 37 | ], 38 | 39 | "Wheelbase": 3.378, 40 | "Minimum Turning Radius": 7.62, 41 | "Maximum Steering Angle (deg)": 30.23, 42 | 43 | "Driveline": { 44 | "Input File": "vehicle/Driveline4WD.json", 45 | "Suspension Indexes": [ 0, 1 ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/PitmanArm.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Pitman Arm Steering", 3 | "Type": "Steering", 4 | "Template": "PitmanArm", 5 | 6 | "Vehicle-Frame Inertia": false, 7 | 8 | "Steering Link": 9 | { 10 | "Mass": 3.681, 11 | "COM": [0.129, 0, 0], 12 | "Moments of Inertia": [0.252, 0.00233, 0.254], 13 | "Products of Inertia": [0, 0, 0], 14 | "Radius": 0.03 15 | }, 16 | 17 | "Pitman Arm": 18 | { 19 | "Mass": 1.605, 20 | "COM": [0.064, 0.249, 0], 21 | "Moments of Inertia": [0.00638, 0.00756, 0.00150], 22 | "Products of Inertia": [0, 0, 0], 23 | "Radius": 0.02 24 | }, 25 | 26 | "Revolute Joint": 27 | { 28 | "Location": [0, 0.249, 0], 29 | "Direction": [0, 0, 1], 30 | "Maximum Angle (deg)": 30 31 | }, 32 | 33 | "Universal Joint": 34 | { 35 | "Location": [ 0.129, 0.249, 0], 36 | "Direction Arm": [0, 0, 1], 37 | "Direction Link": [1, 0, 0] 38 | }, 39 | 40 | "Revolute-Spherical Joint": 41 | { 42 | "Location Chassis": [0, -0.325, 0], 43 | "Location Link": [0.129, -0.325, 0], 44 | "Direction": [0, 0, 1] 45 | }, 46 | 47 | "Tierod Locations": 48 | { 49 | "Pitman Side": [0.195, 0.448, 0.035], 50 | "Idler Side": [0.195, -0.448, 0.035] 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/PitmanArm.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Pitman Arm Steering", 3 | "Type": "Steering", 4 | "Template": "PitmanArm", 5 | 6 | "Vehicle-Frame Inertia": false, 7 | 8 | "Steering Link": 9 | { 10 | "Mass": 3.681, 11 | "COM": [0.129, 0, 0], 12 | "Moments of Inertia": [0.252, 0.00233, 0.254], 13 | "Products of Inertia": [0, 0, 0], 14 | "Radius": 0.03 15 | }, 16 | 17 | "Pitman Arm": 18 | { 19 | "Mass": 1.605, 20 | "COM": [0.064, 0.249, 0], 21 | "Moments of Inertia": [0.00638, 0.00756, 0.00150], 22 | "Products of Inertia": [0, 0, 0], 23 | "Radius": 0.02 24 | }, 25 | 26 | "Revolute Joint": 27 | { 28 | "Location": [0, 0.249, 0], 29 | "Direction": [0, 0, 1], 30 | "Maximum Angle (deg)": 30 31 | }, 32 | 33 | "Universal Joint": 34 | { 35 | "Location": [ 0.129, 0.249, 0], 36 | "Direction Arm": [0, 0, 1], 37 | "Direction Link": [1, 0, 0] 38 | }, 39 | 40 | "Revolute-Spherical Joint": 41 | { 42 | "Location Chassis": [0, -0.325, 0], 43 | "Location Link": [0.129, -0.325, 0], 44 | "Direction": [0, 0, 1] 45 | }, 46 | 47 | "Tierod Locations": 48 | { 49 | "Pitman Side": [0.195, 0.448, 0.035], 50 | "Idler Side": [0.195, -0.448, 0.035] 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/solution/DoubleWishboneReduced.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Reduced DoubleWishbone Suspension", 3 | "Type": "Suspension", 4 | "Template": "DoubleWishboneReduced", 5 | 6 | "Spindle" : 7 | { 8 | "Mass": 1.103, 9 | "COM": [-0.040, 1.100, -0.026], 10 | "Inertia": [0.000478, 0.000496, 0.000478], 11 | "Radius": 0.15, 12 | "Width": 0.06 13 | }, 14 | 15 | "Upright": 16 | { 17 | "Mass": 1.397, 18 | "COM": [-0.040, 0.880, -0.026], 19 | "Inertia": [0.0138, 0.0146, 0.00283], 20 | "Radius": 0.025 21 | }, 22 | 23 | "Upper Control Arm": 24 | { 25 | "Location Chassis Front": [-0.160, 0.539, 0.243], 26 | "Location Chassis Back": [-0.339, 0.587, 0.249], 27 | "Location Upright": [-0.088, 0.808, 0.243] 28 | }, 29 | 30 | "Lower Control Arm": 31 | { 32 | "Location Chassis Front": [0.199, 0.479, -0.206], 33 | "Location Chassis Back": [-0.279, 0.539, -0.200], 34 | "Location Upright": [-0.040, 0.898, -0.265] 35 | }, 36 | 37 | "Tierod": 38 | { 39 | "Location Chassis": [-0.279, 0.479, -0.026], 40 | "Location Upright": [-0.220, 0.898, -0.026] 41 | }, 42 | 43 | "Shock": 44 | { 45 | "Location Chassis": [-0.104, 0.498, 0.323], 46 | "Location Upright": [-0.097, 0.544, -0.038], 47 | "Free Length": 0.356, 48 | "Spring Coefficient": 369150.000, 49 | "Damping Coefficient": 22500.000 50 | }, 51 | 52 | "Axle": 53 | { 54 | "Inertia": 0.4 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/solution/DoubleWishboneReduced.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Reduced DoubleWishbone Suspension", 3 | "Type": "Suspension", 4 | "Template": "DoubleWishboneReduced", 5 | 6 | "Spindle" : 7 | { 8 | "Mass": 1.103, 9 | "COM": [-0.040, 1.100, -0.026], 10 | "Inertia": [0.000478, 0.000496, 0.000478], 11 | "Radius": 0.15, 12 | "Width": 0.06 13 | }, 14 | 15 | "Upright": 16 | { 17 | "Mass": 1.397, 18 | "COM": [-0.040, 0.880, -0.026], 19 | "Inertia": [0.0138, 0.0146, 0.00283], 20 | "Radius": 0.025 21 | }, 22 | 23 | "Upper Control Arm": 24 | { 25 | "Location Chassis Front": [-0.160, 0.539, 0.243], 26 | "Location Chassis Back": [-0.339, 0.587, 0.249], 27 | "Location Upright": [-0.088, 0.808, 0.243] 28 | }, 29 | 30 | "Lower Control Arm": 31 | { 32 | "Location Chassis Front": [0.199, 0.479, -0.206], 33 | "Location Chassis Back": [-0.279, 0.539, -0.200], 34 | "Location Upright": [-0.040, 0.898, -0.265] 35 | }, 36 | 37 | "Tierod": 38 | { 39 | "Location Chassis": [-0.279, 0.479, -0.026], 40 | "Location Upright": [-0.220, 0.898, -0.026] 41 | }, 42 | 43 | "Shock": 44 | { 45 | "Location Chassis": [-0.104, 0.498, 0.323], 46 | "Location Upright": [-0.097, 0.544, -0.038], 47 | "Free Length": 0.356, 48 | "Spring Coefficient": 369150.000, 49 | "Damping Coefficient": 22500.000 50 | }, 51 | 52 | "Axle": 53 | { 54 | "Inertia": 0.4 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Chrono/slider_crank/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MODELS 2 | slider_crank_0 3 | slider_crank_1 4 | slider_crank_2 5 | slider_crank_1_solution 6 | slider_crank_2_solution 7 | ) 8 | 9 | #-------------------------------------------------------------- 10 | # Find the Chrono package with required components 11 | #-------------------------------------------------------------- 12 | 13 | # Invoke find_package in CONFIG mode 14 | find_package(Chrono 15 | COMPONENTS Irrlicht 16 | CONFIG 17 | ) 18 | 19 | # If Chrono and/or the required component(s) were not found, return now. 20 | if(NOT Chrono_FOUND) 21 | message("Could not find requirements for Chrono tutorials") 22 | return() 23 | endif() 24 | 25 | #-------------------------------------------------------------- 26 | # Append to the parent's lists of DLLs (and make them visible) 27 | #-------------------------------------------------------------- 28 | 29 | list(APPEND ALL_DLL_NAMES "${CHRONO_DLL_NAMES}") 30 | set(ALL_DLL_NAMES ${ALL_DLL_NAMES} PARENT_SCOPE) 31 | 32 | # Make CHRONO_PACKAGE_PREFIX_DIR visible above (needed for add_DLL_copy_command) 33 | set(CHRONO_PACKAGE_PREFIX_DIR ${CHRONO_PACKAGE_PREFIX_DIR} PARENT_SCOPE) 34 | 35 | #-------------------------------------------------------------- 36 | # Compilation flags 37 | #-------------------------------------------------------------- 38 | 39 | foreach(PROGRAM ${MODELS}) 40 | message(STATUS "...add ${PROGRAM}") 41 | 42 | add_executable(${PROGRAM} "${PROGRAM}.cpp") 43 | source_group("" FILES "${PROGRAM}.cpp") 44 | 45 | set_property(TARGET ${PROGRAM} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "$") 46 | 47 | target_compile_definitions(${PROGRAM} PUBLIC "CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\"") 48 | target_link_libraries(${PROGRAM} PRIVATE ${CHRONO_TARGETS}) 49 | endforeach() 50 | -------------------------------------------------------------------------------- /Chrono/multicore/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MODELS 2 | cratering 3 | cratering_solution_1 4 | cratering_solution_2 5 | cratering_solution_3 6 | ) 7 | 8 | #-------------------------------------------------------------- 9 | # Find the Chrono package with required components 10 | #-------------------------------------------------------------- 11 | 12 | # Invoke find_package in CONFIG mode 13 | find_package(Chrono 14 | COMPONENTS Multicore 15 | OPTIONAL_COMPONENTS VSG 16 | CONFIG 17 | ) 18 | 19 | # If Chrono and/or the required component(s) were not found, return now. 20 | if(NOT Chrono_FOUND) 21 | message("Could not find requirements for Chrono::Multicore tutorials") 22 | return() 23 | endif() 24 | 25 | #-------------------------------------------------------------- 26 | # Append to the parent's lists of DLLs (and make them visible) 27 | #-------------------------------------------------------------- 28 | 29 | list(APPEND ALL_DLL_NAMES "${CHRONO_DLL_NAMES}") 30 | set(ALL_DLL_NAMES ${ALL_DLL_NAMES} PARENT_SCOPE) 31 | 32 | # Make CHRONO_PACKAGE_PREFIX_DIR visible above (needed for add_DLL_copy_command) 33 | set(CHRONO_PACKAGE_PREFIX_DIR ${CHRONO_PACKAGE_PREFIX_DIR} PARENT_SCOPE) 34 | 35 | #-------------------------------------------------------------- 36 | # Compilation flags 37 | #-------------------------------------------------------------- 38 | 39 | foreach(PROGRAM ${MODELS}) 40 | message(STATUS "...add ${PROGRAM}") 41 | 42 | add_executable(${PROGRAM} "${PROGRAM}.cpp") 43 | source_group("" FILES "${PROGRAM}.cpp") 44 | 45 | set_property(TARGET ${PROGRAM} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "$") 46 | 47 | target_compile_definitions(${PROGRAM} PUBLIC "CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\"") 48 | target_link_libraries(${PROGRAM} PRIVATE ${CHRONO_TARGETS}) 49 | endforeach() 50 | -------------------------------------------------------------------------------- /Chrono/FEA/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MODELS 2 | FEA_cable_collide_1 3 | FEA_cable_collide_2 4 | FEA_cable_collide_3 5 | FEA_cable_collide_1_solution 6 | FEA_cable_collide_2_solution 7 | FEA_cable_collide_3_solution 8 | ) 9 | 10 | #-------------------------------------------------------------- 11 | # Find the Chrono package with required components 12 | #-------------------------------------------------------------- 13 | 14 | # Invoke find_package in CONFIG mode 15 | find_package(Chrono 16 | COMPONENTS Irrlicht 17 | CONFIG 18 | ) 19 | 20 | # If Chrono and/or the required component(s) were not found, return now. 21 | if(NOT Chrono_FOUND) 22 | message("Could not find requirements for Chrono tutorials") 23 | return() 24 | endif() 25 | 26 | #-------------------------------------------------------------- 27 | # Append to the parent's lists of DLLs (and make them visible) 28 | #-------------------------------------------------------------- 29 | 30 | list(APPEND ALL_DLL_NAMES "${CHRONO_DLL_NAMES}") 31 | set(ALL_DLL_NAMES ${ALL_DLL_NAMES} PARENT_SCOPE) 32 | 33 | # Make CHRONO_PACKAGE_PREFIX_DIR visible above (needed for add_DLL_copy_command) 34 | set(CHRONO_PACKAGE_PREFIX_DIR ${CHRONO_PACKAGE_PREFIX_DIR} PARENT_SCOPE) 35 | 36 | #-------------------------------------------------------------- 37 | # Compilation flags 38 | #-------------------------------------------------------------- 39 | 40 | foreach(PROGRAM ${MODELS}) 41 | message(STATUS "...add ${PROGRAM}") 42 | 43 | add_executable(${PROGRAM} "${PROGRAM}.cpp") 44 | source_group("" FILES "${PROGRAM}.cpp") 45 | 46 | set_property(TARGET ${PROGRAM} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "$") 47 | 48 | target_compile_definitions(${PROGRAM} PUBLIC "CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\"") 49 | target_link_libraries(${PROGRAM} PRIVATE ${CHRONO_TARGETS}) 50 | endforeach() 51 | -------------------------------------------------------------------------------- /Chrono/sensor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MODELS 2 | sensor_gator 3 | sensor_gator_solution 4 | ) 5 | 6 | #-------------------------------------------------------------- 7 | # Find the Chrono package with required components 8 | #-------------------------------------------------------------- 9 | 10 | # Invoke find_package in CONFIG mode 11 | find_package(Chrono 12 | COMPONENTS Vehicle Irrlicht Sensor 13 | CONFIG 14 | ) 15 | 16 | # If Chrono and/or the required component(s) were not found, return now. 17 | if(NOT Chrono_FOUND) 18 | message("Could not find requirements for Chrono::Sensor tutorials") 19 | return() 20 | endif() 21 | 22 | #-------------------------------------------------------------- 23 | # Append to the parent's lists of DLLs (and make them visible) 24 | #-------------------------------------------------------------- 25 | 26 | list(APPEND ALL_DLL_NAMES "${CHRONO_DLL_NAMES}") 27 | set(ALL_DLL_NAMES ${ALL_DLL_NAMES} PARENT_SCOPE) 28 | 29 | # Make CHRONO_PACKAGE_PREFIX_DIR visible above (needed for add_DLL_copy_command) 30 | set(CHRONO_PACKAGE_PREFIX_DIR ${CHRONO_PACKAGE_PREFIX_DIR} PARENT_SCOPE) 31 | 32 | #-------------------------------------------------------------- 33 | # Compilation flags 34 | #-------------------------------------------------------------- 35 | 36 | find_package(Threads REQUIRED) 37 | 38 | foreach(PROGRAM ${MODELS}) 39 | message(STATUS "...add ${PROGRAM}") 40 | 41 | add_executable(${PROGRAM} "${PROGRAM}.cpp") 42 | source_group("" FILES "${PROGRAM}.cpp") 43 | 44 | set_property(TARGET ${PROGRAM} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "$") 45 | 46 | target_compile_definitions(${PROGRAM} PUBLIC "CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\"") 47 | target_compile_definitions(${PROGRAM} PUBLIC "CHRONO_VEHICLE_DATA_DIR=\"${CHRONO_VEHICLE_DATA_DIR}\"") 48 | target_compile_definitions(${PROGRAM} PUBLIC "SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"") 49 | target_link_libraries(${PROGRAM} PRIVATE ${CHRONO_TARGETS}) 50 | endforeach() 51 | -------------------------------------------------------------------------------- /Chrono/synchrono/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MODELS 2 | intersection 3 | intersection_solution 4 | ) 5 | 6 | #-------------------------------------------------------------- 7 | # Find the Chrono package with required components 8 | #-------------------------------------------------------------- 9 | 10 | # Invoke find_package in CONFIG mode 11 | find_package(Chrono QUIET 12 | COMPONENTS Vehicle Synchrono 13 | OPTIONAL_COMPONENTS Irrlicht Sensor 14 | CONFIG 15 | ) 16 | 17 | # If Chrono and/or the required component(s) were not found, return now. 18 | if(NOT Chrono_FOUND) 19 | message("Could not find requirements for Chrono::Sensor tutorials") 20 | return() 21 | endif() 22 | 23 | #-------------------------------------------------------------- 24 | # Append to the parent's lists of DLLs (and make them visible) 25 | #-------------------------------------------------------------- 26 | 27 | list(APPEND ALL_DLL_NAMES "${CHRONO_DLL_NAMES}") 28 | set(ALL_DLL_NAMES ${ALL_DLL_NAMES} PARENT_SCOPE) 29 | 30 | # Make CHRONO_PACKAGE_PREFIX_DIR visible above (needed for add_DLL_copy_command) 31 | set(CHRONO_PACKAGE_PREFIX_DIR ${CHRONO_PACKAGE_PREFIX_DIR} PARENT_SCOPE) 32 | 33 | #-------------------------------------------------------------- 34 | # Compilation flags 35 | #-------------------------------------------------------------- 36 | 37 | foreach(PROGRAM ${MODELS}) 38 | message(STATUS "...add ${PROGRAM}") 39 | 40 | add_executable(${PROGRAM} "${PROGRAM}.cpp") 41 | source_group("" FILES "${PROGRAM}.cpp") 42 | 43 | set_property(TARGET ${PROGRAM} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "$") 44 | 45 | target_compile_definitions(${PROGRAM} PUBLIC "CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\"") 46 | target_compile_definitions(${PROGRAM} PUBLIC "CHRONO_VEHICLE_DATA_DIR=\"${CHRONO_VEHICLE_DATA_DIR}\"") 47 | target_compile_definitions(${PROGRAM} PUBLIC "SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"") 48 | target_link_libraries(${PROGRAM} PRIVATE ${CHRONO_TARGETS}) 49 | endforeach() -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MODELS 2 | wheeled_vehicle 3 | wheeled_vehicle_solution 4 | ) 5 | 6 | #-------------------------------------------------------------- 7 | # Find the Chrono package with required components 8 | #-------------------------------------------------------------- 9 | 10 | # Invoke find_package in CONFIG mode 11 | find_package(Chrono 12 | COMPONENTS Vehicle Irrlicht 13 | OPTIONAL_COMPONENTS VSG 14 | CONFIG 15 | ) 16 | 17 | # If Chrono and/or the required component(s) were not found, return now. 18 | if(NOT Chrono_FOUND) 19 | message("Could not find requirements for Chrono::Vehicle tutorials") 20 | return() 21 | endif() 22 | 23 | #-------------------------------------------------------------- 24 | # Append to the parent's lists of DLLs (and make them visible) 25 | #-------------------------------------------------------------- 26 | 27 | list(APPEND ALL_DLL_NAMES "${CHRONO_DLL_NAMES}") 28 | set(ALL_DLL_NAMES ${ALL_DLL_NAMES} PARENT_SCOPE) 29 | 30 | # Make CHRONO_PACKAGE_PREFIX_DIR visible above (needed for add_DLL_copy_command) 31 | set(CHRONO_PACKAGE_PREFIX_DIR ${CHRONO_PACKAGE_PREFIX_DIR} PARENT_SCOPE) 32 | 33 | #-------------------------------------------------------------- 34 | # Compilation flags 35 | #-------------------------------------------------------------- 36 | 37 | foreach(PROGRAM ${MODELS}) 38 | message(STATUS "...add ${PROGRAM}") 39 | 40 | add_executable(${PROGRAM} "${PROGRAM}.cpp") 41 | source_group("" FILES "${PROGRAM}.cpp") 42 | 43 | set_property(TARGET ${PROGRAM} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "$") 44 | 45 | target_compile_definitions(${PROGRAM} PUBLIC "CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\"") 46 | target_compile_definitions(${PROGRAM} PUBLIC "CHRONO_VEHICLE_DATA_DIR=\"${CHRONO_VEHICLE_DATA_DIR}\"") 47 | target_compile_definitions(${PROGRAM} PUBLIC "SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"") 48 | target_link_libraries(${PROGRAM} PRIVATE ${CHRONO_TARGETS}) 49 | endforeach() 50 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/MultiLink.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Multi-Link Suspension", 3 | "Type": "Suspension", 4 | "Template": "MultiLink", 5 | 6 | "Spindle" : 7 | { 8 | "Mass": 1.103, 9 | "COM": [0.000, 0.950, 0.000], 10 | "Inertia": [0.000478, 0.000478, 0.000496], 11 | "Radius": 0.15, 12 | "Width": 0.03 13 | }, 14 | 15 | "Upright": 16 | { 17 | "Mass": 3.201, 18 | "COM": [0.000, 0.910, 0.000], 19 | "Inertia": [0.0250, 0.00653, 0.0284], 20 | "Radius": 0.02 21 | }, 22 | 23 | "Upper Arm": 24 | { 25 | "Mass": 4.744, 26 | "COM": [-0.014, 0.640, 0.098], 27 | "Inertia": [0.0237, 0.0294, 0.00612], 28 | "Radius": 0.02, 29 | "Location Chassis Front": [0.060, 0.547, 0.082], 30 | "Location Chassis Back": [-0.157, 0.508, 0.062], 31 | "Location Upright": [0.056, 0.864, 0.151] 32 | }, 33 | 34 | "Lateral": 35 | { 36 | "Mass": 1.910, 37 | "COM": [0.033, 0.590, -0.113], 38 | "Inertia": [0.0543, 0.0541, 0.000279], 39 | "Radius": 0.02, 40 | "Location Chassis": [0.036, 0.338, -0.133], 41 | "Location Upright": [0.029, 0.842, -0.093], 42 | "Universal Joint Axis Link": [-0.978950, 0.204099, 0.0], 43 | "Universal Joint Axis Chassis": [-0.021990, -0.105472, 0.994179] 44 | }, 45 | 46 | "Trailing Link": 47 | { 48 | "Mass": 15.204, 49 | "COM": [0.279, 0.693, -0.132], 50 | "Inertia": [0.0762, 0.527, 0.567], 51 | "Radius": 0.03, 52 | "Location Chassis": [0.723, 0.599, -0.072], 53 | "Location Upright": [-0.000, 0.864, -0.156], 54 | "Universal Joint Axis Link": [0.0, 0.0, 1.0], 55 | "Universal Joint Axis Chassis": [-0.272, 0.962, 0.0] 56 | }, 57 | 58 | "Tierod": 59 | { 60 | "Location Chassis": [-0.257, 0.320, -0.116], 61 | "Location Upright": [-0.144, 0.862, -0.056] 62 | }, 63 | 64 | "Spring": 65 | { 66 | "Location Chassis": [0.181, 0.641, 0.110], 67 | "Location Link": [0.181, 0.669, -0.164], 68 | "Spring Coefficient": 167062.000, 69 | "Free Length" : 0.339 70 | }, 71 | 72 | "Shock": 73 | { 74 | "Location Chassis": [0.171, 0.628, 0.315], 75 | "Location Link": [0.181, 0.669, -0.162], 76 | "Damping Coefficient": 60068.000 77 | }, 78 | 79 | "Axle": 80 | { 81 | "Inertia": 0.166 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/MultiLink.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Multi-Link Suspension", 3 | "Type": "Suspension", 4 | "Template": "MultiLink", 5 | 6 | "Spindle" : 7 | { 8 | "Mass": 1.103, 9 | "COM": [0.000, 0.950, 0.000], 10 | "Inertia": [0.000478, 0.000478, 0.000496], 11 | "Radius": 0.15, 12 | "Width": 0.03 13 | }, 14 | 15 | "Upright": 16 | { 17 | "Mass": 3.201, 18 | "COM": [0.000, 0.910, 0.000], 19 | "Inertia": [0.0250, 0.00653, 0.0284], 20 | "Radius": 0.02 21 | }, 22 | 23 | "Upper Arm": 24 | { 25 | "Mass": 4.744, 26 | "COM": [-0.014, 0.640, 0.098], 27 | "Inertia": [0.0237, 0.0294, 0.00612], 28 | "Radius": 0.02, 29 | "Location Chassis Front": [0.060, 0.547, 0.082], 30 | "Location Chassis Back": [-0.157, 0.508, 0.062], 31 | "Location Upright": [0.056, 0.864, 0.151] 32 | }, 33 | 34 | "Lateral": 35 | { 36 | "Mass": 1.910, 37 | "COM": [0.033, 0.590, -0.113], 38 | "Inertia": [0.0543, 0.0541, 0.000279], 39 | "Radius": 0.02, 40 | "Location Chassis": [0.036, 0.338, -0.133], 41 | "Location Upright": [0.029, 0.842, -0.093], 42 | "Universal Joint Axis Link": [-0.978950, 0.204099, 0.0], 43 | "Universal Joint Axis Chassis": [-0.021990, -0.105472, 0.994179] 44 | }, 45 | 46 | "Trailing Link": 47 | { 48 | "Mass": 15.204, 49 | "COM": [0.279, 0.693, -0.132], 50 | "Inertia": [0.0762, 0.527, 0.567], 51 | "Radius": 0.03, 52 | "Location Chassis": [0.723, 0.599, -0.072], 53 | "Location Upright": [-0.000, 0.864, -0.156], 54 | "Universal Joint Axis Link": [0.0, 0.0, 1.0], 55 | "Universal Joint Axis Chassis": [-0.272, 0.962, 0.0] 56 | }, 57 | 58 | "Tierod": 59 | { 60 | "Location Chassis": [-0.257, 0.320, -0.116], 61 | "Location Upright": [-0.144, 0.862, -0.056] 62 | }, 63 | 64 | "Spring": 65 | { 66 | "Location Chassis": [0.181, 0.641, 0.110], 67 | "Location Link": [0.181, 0.669, -0.164], 68 | "Spring Coefficient": 167062.000, 69 | "Free Length" : 0.339 70 | }, 71 | 72 | "Shock": 73 | { 74 | "Location Chassis": [0.171, 0.628, 0.315], 75 | "Location Link": [0.181, 0.669, -0.162], 76 | "Damping Coefficient": 60068.000 77 | }, 78 | 79 | "Axle": 80 | { 81 | "Inertia": 0.166 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/data/vehicle/DoubleWishbone.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Double Wishbone Suspension", 3 | "Type": "Suspension", 4 | "Template": "DoubleWishbone", 5 | 6 | "Vehicle-Frame Inertia": false, 7 | 8 | "Camber Angle (deg)": 0, 9 | "Toe Angle (deg)": 0, 10 | 11 | "Spindle": { 12 | "Mass": 14.705, 13 | "COM": [ -0.040, 0.910, -0.026 ], 14 | "Inertia": [ 0.04117, 0.07352, 0.04117 ], 15 | "Radius": 0.15, 16 | "Width": 0.06 17 | }, 18 | 19 | "Upright": { 20 | "Mass": 19.450, 21 | "COM": [ -0.040, 0.751, -0.026 ], 22 | "Moments of Inertia": [ 0.1656, 0.1934, 0.04367 ], 23 | "Products of Inertia": [ 0, 0, 0 ], 24 | "Radius": 0.04 25 | }, 26 | 27 | "Upper Control Arm": { 28 | "Mass": 5.813, 29 | "COM": [ -0.106, 0.589, 0.218 ], 30 | "Moments of Inertia": [ 0.03, 0.03, 0.06276 ], 31 | "Products of Inertia": [ 0, 0, 0 ], 32 | "Radius": 0.02, 33 | "Location Chassis Front": [ -0.048, 0.446, 0.245 ], 34 | "Location Chassis Back": [ -0.268, 0.478, 0.196 ], 35 | "Location Upright": [ -0.053, 0.716, 0.215 ] 36 | }, 37 | 38 | "Lower Control Arm": { 39 | "Mass": 23.965, 40 | "COM": [ 0.000, 0.547, -0.059 ], 41 | "Moments of Inertia": [ 0.4, 0.4, 0.8938 ], 42 | "Products of Inertia": [ 0, 0, 0 ], 43 | "Radius": 0.03, 44 | "Location Chassis Front": [ 0.223, 0.307, 0.000 ], 45 | "Location Chassis Back": [ -0.223, 0.307, 0.000 ], 46 | "Location Upright": [ -0.036, 0.787, -0.118 ] 47 | }, 48 | 49 | "Tierod": { 50 | "Location Chassis": [ -0.250, 0.448, 0.054 ], 51 | "Location Upright": [ -0.176, 0.821, -0.016 ] 52 | }, 53 | 54 | "Spring": { 55 | "Location Chassis": [ 0.104, 0.510, 0.197 ], 56 | "Location Arm": [ 0.097, 0.543, -0.047 ], 57 | "Minimum Length": 0.15, 58 | "Maximum Length": 0.3, 59 | "Spring Curve Data": [ 60 | [ -0.2, -322095.536 ], 61 | [ -0.18, -240521.166 ], 62 | [ -0.16, -174535.686 ], 63 | [ -0.14, -122406.996 ], 64 | [ -0.12, -82402.997 ], 65 | [ -0.1, -52791.592 ], 66 | [ -0.08, -31840.681 ], 67 | [ -0.06, -17818.165 ], 68 | [ -0.04, -8991.945 ], 69 | [ -0.02, -3629.923 ], 70 | [ 0, 0 ], 71 | [ 0.02, 3629.923 ], 72 | [ 0.04, 8991.945 ], 73 | [ 0.06, 17818.165 ], 74 | [ 0.08, 31840.681 ], 75 | [ 0.1, 52791.592 ], 76 | [ 0.12, 82402.997 ], 77 | [ 0.14, 122406.996 ], 78 | [ 0.16, 174535.686 ], 79 | [ 0.18, 240521.166 ], 80 | [ 0.2, 322095.536 ] 81 | ], 82 | "Free Length": 0.339 83 | }, 84 | 85 | "Shock": { 86 | "Location Chassis": [ 0.104, 0.498, 0.323 ], 87 | "Location Arm": [ 0.097, 0.543, -0.047 ], 88 | "Damping Coefficient": 19015.5692 89 | }, 90 | 91 | "Axle": { 92 | "Inertia": 0.4 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/data/vehicle/DoubleWishbone.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Double Wishbone Suspension", 3 | "Type": "Suspension", 4 | "Template": "DoubleWishbone", 5 | 6 | "Vehicle-Frame Inertia": false, 7 | 8 | "Camber Angle (deg)": 0, 9 | "Toe Angle (deg)": 0, 10 | 11 | "Spindle": { 12 | "Mass": 14.705, 13 | "COM": [ -0.040, 0.910, -0.026 ], 14 | "Inertia": [ 0.04117, 0.07352, 0.04117 ], 15 | "Radius": 0.15, 16 | "Width": 0.06 17 | }, 18 | 19 | "Upright": { 20 | "Mass": 19.450, 21 | "COM": [ -0.040, 0.751, -0.026 ], 22 | "Moments of Inertia": [ 0.1656, 0.1934, 0.04367 ], 23 | "Products of Inertia": [ 0, 0, 0 ], 24 | "Radius": 0.04 25 | }, 26 | 27 | "Upper Control Arm": { 28 | "Mass": 5.813, 29 | "COM": [ -0.106, 0.589, 0.218 ], 30 | "Moments of Inertia": [ 0.03, 0.03, 0.06276 ], 31 | "Products of Inertia": [ 0, 0, 0 ], 32 | "Radius": 0.02, 33 | "Location Chassis Front": [ -0.048, 0.446, 0.245 ], 34 | "Location Chassis Back": [ -0.268, 0.478, 0.196 ], 35 | "Location Upright": [ -0.053, 0.716, 0.215 ] 36 | }, 37 | 38 | "Lower Control Arm": { 39 | "Mass": 23.965, 40 | "COM": [ 0.000, 0.547, -0.059 ], 41 | "Moments of Inertia": [ 0.4, 0.4, 0.8938 ], 42 | "Products of Inertia": [ 0, 0, 0 ], 43 | "Radius": 0.03, 44 | "Location Chassis Front": [ 0.223, 0.307, 0.000 ], 45 | "Location Chassis Back": [ -0.223, 0.307, 0.000 ], 46 | "Location Upright": [ -0.036, 0.787, -0.118 ] 47 | }, 48 | 49 | "Tierod": { 50 | "Location Chassis": [ -0.250, 0.448, 0.054 ], 51 | "Location Upright": [ -0.176, 0.821, -0.016 ] 52 | }, 53 | 54 | "Spring": { 55 | "Location Chassis": [ 0.104, 0.510, 0.197 ], 56 | "Location Arm": [ 0.097, 0.543, -0.047 ], 57 | "Minimum Length": 0.15, 58 | "Maximum Length": 0.3, 59 | "Spring Curve Data": [ 60 | [ -0.2, -322095.536 ], 61 | [ -0.18, -240521.166 ], 62 | [ -0.16, -174535.686 ], 63 | [ -0.14, -122406.996 ], 64 | [ -0.12, -82402.997 ], 65 | [ -0.1, -52791.592 ], 66 | [ -0.08, -31840.681 ], 67 | [ -0.06, -17818.165 ], 68 | [ -0.04, -8991.945 ], 69 | [ -0.02, -3629.923 ], 70 | [ 0, 0 ], 71 | [ 0.02, 3629.923 ], 72 | [ 0.04, 8991.945 ], 73 | [ 0.06, 17818.165 ], 74 | [ 0.08, 31840.681 ], 75 | [ 0.1, 52791.592 ], 76 | [ 0.12, 82402.997 ], 77 | [ 0.14, 122406.996 ], 78 | [ 0.16, 174535.686 ], 79 | [ 0.18, 240521.166 ], 80 | [ 0.2, 322095.536 ] 81 | ], 82 | "Free Length": 0.339 83 | }, 84 | 85 | "Shock": { 86 | "Location Chassis": [ 0.104, 0.498, 0.323 ], 87 | "Location Arm": [ 0.097, 0.543, -0.047 ], 88 | "Damping Coefficient": 19015.5692 89 | }, 90 | 91 | "Axle": { 92 | "Inertia": 0.4 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/solution/SolidAxle.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Generic Solid Axle", 3 | "Type": "Suspension", 4 | "Template": "SolidAxle", 5 | 6 | "Spindle" : 7 | { 8 | "Mass": 0.248, 9 | "COM": [0, 0.910, 0], 10 | "Inertia": [0.0000558, 0.0000279, 0.0000558], 11 | "Radius": 0.06, 12 | "Width": 0.04 13 | }, 14 | 15 | "Knuckle": 16 | { 17 | "Mass": 1.356, 18 | "COM": [0, 0.7, 0], 19 | "Inertia": [0.00255, 0.00134, 0.00196], 20 | "Radius": 0.01, 21 | "Location Lower": [0.005, 0.7, -0.05], 22 | "Location Upper": [-0.015, 0.675, 0.075] 23 | }, 24 | 25 | "Upper Link": 26 | { 27 | "Mass": 1.446, 28 | "COM": [0.15, 0.4875, 0.15], 29 | "Inertia": [0.011, 0.011, 0.000142], 30 | "Radius": 0.02, 31 | "Location Axle": [-0.055, 0.475, 0.15], 32 | "Location Chassis": [0.355, 0.5, 0.15] 33 | }, 34 | 35 | "Lower Link": 36 | { 37 | "Mass": 2.892, 38 | "COM": [0.23, 0.475, -0.06], 39 | "Inertia": [0.0514, 0.0514, 0.00037], 40 | "Radius": 0.02, 41 | "Location Axle": [0.01, 0.6, -0.075], 42 | "Location Chassis": [0.45, 0.35, -0.045] 43 | }, 44 | 45 | "Axle Tube" : 46 | { 47 | "Mass": 44.958, 48 | "COM": [0, 0, 0], 49 | "Inertia": [7.744, 0.045, 7.744], 50 | "Radius": 0.03 51 | }, 52 | 53 | "Tierod": 54 | { 55 | "Mass": 1.633, 56 | "Inertia": [0.252, 0.001, 0.252], 57 | "Location Knuckle": [-0.075, 0.68, -0.065], 58 | "Radius": 0.003 59 | }, 60 | 61 | "Draglink": 62 | { 63 | "Mass": 0.464, 64 | "Inertia": [0.005, 0.005, 0.001], 65 | "Location Chassis": [0.385, 0.45, -0.02], 66 | "Location Bell Crank": [0, 0.425, -0.05], 67 | "Radius": 0.003 68 | }, 69 | 70 | "Bell Crank": 71 | { 72 | "Mass": 0.218, 73 | "Inertia": [0.001, 0.001, 0.001], 74 | "Location Tierod": [-0.075, 0.325, -0.065], 75 | "Location Axle": [0, 0.325, -0.05], 76 | "Radius": 0.003 77 | }, 78 | 79 | "Spring": 80 | { 81 | "Location Chassis": [-0.080, 0.56, 0.3], 82 | "Location Axle": [-0.065, 0.575, -0.025], 83 | "Spring Coefficient": 267062.000, 84 | "Free Length": 0.3948 85 | }, 86 | 87 | "Shock": 88 | { 89 | "Location Chassis": [-0.080, 0.56, 0.3], 90 | "Location Axle": [-0.065, 0.575, -0.025], 91 | "Damping Coefficient": 22459.000 92 | }, 93 | 94 | "Axle": 95 | { 96 | "Inertia": 0.4 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/solution/SolidAxle.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name": "Generic Solid Axle", 3 | "Type": "Suspension", 4 | "Template": "SolidAxle", 5 | 6 | "Spindle" : 7 | { 8 | "Mass": 0.248, 9 | "COM": [0, 0.910, 0], 10 | "Inertia": [0.0000558, 0.0000279, 0.0000558], 11 | "Radius": 0.06, 12 | "Width": 0.04 13 | }, 14 | 15 | "Knuckle": 16 | { 17 | "Mass": 1.356, 18 | "COM": [0, 0.7, 0], 19 | "Inertia": [0.00255, 0.00134, 0.00196], 20 | "Radius": 0.01, 21 | "Location Lower": [0.005, 0.7, -0.05], 22 | "Location Upper": [-0.015, 0.675, 0.075] 23 | }, 24 | 25 | "Upper Link": 26 | { 27 | "Mass": 1.446, 28 | "COM": [0.15, 0.4875, 0.15], 29 | "Inertia": [0.011, 0.011, 0.000142], 30 | "Radius": 0.02, 31 | "Location Axle": [-0.055, 0.475, 0.15], 32 | "Location Chassis": [0.355, 0.5, 0.15] 33 | }, 34 | 35 | "Lower Link": 36 | { 37 | "Mass": 2.892, 38 | "COM": [0.23, 0.475, -0.06], 39 | "Inertia": [0.0514, 0.0514, 0.00037], 40 | "Radius": 0.02, 41 | "Location Axle": [0.01, 0.6, -0.075], 42 | "Location Chassis": [0.45, 0.35, -0.045] 43 | }, 44 | 45 | "Axle Tube" : 46 | { 47 | "Mass": 44.958, 48 | "COM": [0, 0, 0], 49 | "Inertia": [7.744, 0.045, 7.744], 50 | "Radius": 0.03 51 | }, 52 | 53 | "Tierod": 54 | { 55 | "Mass": 1.633, 56 | "Inertia": [0.252, 0.001, 0.252], 57 | "Location Knuckle": [-0.075, 0.68, -0.065], 58 | "Radius": 0.003 59 | }, 60 | 61 | "Draglink": 62 | { 63 | "Mass": 0.464, 64 | "Inertia": [0.005, 0.005, 0.001], 65 | "Location Chassis": [0.385, 0.45, -0.02], 66 | "Location Bell Crank": [0, 0.425, -0.05], 67 | "Radius": 0.003 68 | }, 69 | 70 | "Bell Crank": 71 | { 72 | "Mass": 0.218, 73 | "Inertia": [0.001, 0.001, 0.001], 74 | "Location Tierod": [-0.075, 0.325, -0.065], 75 | "Location Axle": [0, 0.325, -0.05], 76 | "Radius": 0.003 77 | }, 78 | 79 | "Spring": 80 | { 81 | "Location Chassis": [-0.080, 0.56, 0.3], 82 | "Location Axle": [-0.065, 0.575, -0.025], 83 | "Spring Coefficient": 267062.000, 84 | "Free Length": 0.3948 85 | }, 86 | 87 | "Shock": 88 | { 89 | "Location Chassis": [-0.080, 0.56, 0.3], 90 | "Location Axle": [-0.065, 0.575, -0.025], 91 | "Damping Coefficient": 22459.000 92 | }, 93 | 94 | "Axle": 95 | { 96 | "Inertia": 0.4 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #============================================================================= 2 | # CMake configuration file for Chrono-Tutorial 3 | # 4 | #============================================================================= 5 | 6 | cmake_minimum_required(VERSION 3.18) 7 | cmake_policy(SET CMP0091 NEW) 8 | 9 | project(ChronoTutorial) 10 | 11 | # Set location of executable 12 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) 13 | 14 | #----------------------------------------------------------------------------- 15 | # Always use full RPATH (differentiating between the build and install trees) 16 | #----------------------------------------------------------------------------- 17 | 18 | # use, i.e. don't skip the full RPATH for the build tree 19 | set(CMAKE_SKIP_BUILD_RPATH FALSE) 20 | 21 | # when building, don't use the install RPATH already 22 | # (but later on when installing) 23 | set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 24 | 25 | set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") 26 | 27 | # add the automatically determined parts of the RPATH 28 | # which point to directories outside the build tree to the install RPATH 29 | set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 30 | 31 | # the RPATH to be used when installing, but only if it's not a system directory 32 | list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) 33 | if("${isSystemDir}" STREQUAL "-1") 34 | set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") 35 | endif() 36 | 37 | #----------------------------------------------------------------------------- 38 | # Force C++11 39 | #----------------------------------------------------------------------------- 40 | 41 | #if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 42 | # set(CH_LINKERFLAG_EXE "${CH_LINKERFLAG_EXE} -framework IOKit -framework Cocoa -framework OpenGL") 43 | #endif() 44 | 45 | #----------------------------------------------------------------------------- 46 | # Fix for VS 2017 15.8 and newer to handle alignment specification with Eigen 47 | #----------------------------------------------------------------------------- 48 | 49 | if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") 50 | if(MSVC AND ${MSVC_VERSION} GREATER_EQUAL 1915) 51 | add_definitions( "-D_ENABLE_EXTENDED_ALIGNED_STORAGE" ) 52 | endif() 53 | endif() 54 | 55 | #----------------------------------------------------------------------------- 56 | # Disable some warnings 57 | #----------------------------------------------------------------------------- 58 | 59 | if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") 60 | if(MSVC) 61 | add_definitions( "-D_CRT_SECURE_NO_DEPRECATE" ) # avoids deprecation warnings 62 | add_definitions( "-D_SCL_SECURE_NO_DEPRECATE" ) # avoids deprecation warnings 63 | add_definitions( "-DNOMINMAX" ) # do not use MSVC's min/max macros 64 | add_definitions( "-MP" ) # perform parallel builds 65 | endif(MSVC) 66 | endif() 67 | 68 | #----------------------------------------------------------------------------- 69 | # Invoke CMake in subdirectories 70 | #----------------------------------------------------------------------------- 71 | 72 | if(NOT Chrono_DIR) 73 | set(Chrono_DIR "" CACHE PATH "The directory containing a CMake configuration file for Chrono.") 74 | return() 75 | endif() 76 | 77 | # Options for configuring/building individual sets of programs 78 | option(ENABLE_CHRONO_PROGRAMS "Build the C++ Chrono tutorial programs" ON) 79 | option(ENABLE_VEHICLE_PROGRAMS "Build the C++ Chrono::Vehicle tutorial programs" ON) 80 | option(ENABLE_FEA_PROGRAMS "Build the C++ Chrono::FEA tutorial programs" ON) 81 | option(ENABLE_MULTICORE_PROGRAMS "Build the C++ Chrono::Multicore tutorial programs" ON) 82 | option(ENABLE_SENSOR_PROGRAMS "Build the C++ Chrono::Sensor tutorial programs" ON) 83 | option(ENABLE_SYNCHRONO_PROGRAMS "Build the C++ SynChrono tutorial programs" ON) 84 | 85 | # Keep track of all DLLs. Each submodule should append to these list. 86 | list(APPEND ALL_DLL_NAMES "") 87 | 88 | # Propagate configuration to submodules. 89 | if(ENABLE_CHRONO_PROGRAMS) 90 | message(STATUS "\n==== Chrono tutorials ====\n") 91 | add_subdirectory(Chrono/slider_crank) 92 | endif() 93 | if(ENABLE_VEHICLE_PROGRAMS) 94 | message(STATUS "\n==== Chrono::Vehicle tutorials ====\n") 95 | add_subdirectory(Chrono/wheeled_vehicle) 96 | endif() 97 | if(ENABLE_FEA_PROGRAMS) 98 | message(STATUS "\n==== Chrono::FEA tutorials ====\n") 99 | add_subdirectory(Chrono/FEA) 100 | endif() 101 | if(ENABLE_MULTICORE_PROGRAMS) 102 | message(STATUS "\n==== Chrono::Multicore tutorials ====\n") 103 | add_subdirectory(Chrono/multicore) 104 | endif() 105 | if(ENABLE_SENSOR_PROGRAMS) 106 | message(STATUS "\n==== Chrono::Sensor tutorials ====\n") 107 | add_subdirectory(Chrono/sensor) 108 | endif() 109 | if(ENABLE_SYNCHRONO_PROGRAMS) 110 | message(STATUS "\n==== Chrono::SynChrono tutorials ====\n") 111 | add_subdirectory(Chrono/synchrono) 112 | endif() 113 | 114 | #-------------------------------------------------------------- 115 | # Copy DLLs 116 | #-------------------------------------------------------------- 117 | 118 | # Add custom command for copying DLLs to the appropriate binary output folder 119 | # (no-op if not Windows) 120 | add_CHRONO_DLLS_copy_command("${ALL_DLL_NAMES}") 121 | -------------------------------------------------------------------------------- /PyChrono/slider-crank/slider_crank_0.py: -------------------------------------------------------------------------------- 1 | ## ============================================================================= 2 | ## PROJECT CHRONO - http:##projectchrono.org 3 | ## 4 | ## Copyright (c) 2014 projectchrono.org 5 | ## All right reserved. 6 | ## 7 | ## Use of this source code is governed by a BSD-style license that can be found 8 | ## in the LICENSE file at the top level of the distribution and at 9 | ## http://projectchrono.org/license-chrono.txt. 10 | ## 11 | ## ============================================================================= 12 | ## Author: Simone Benatti 13 | ## ============================================================================= 14 | ## 15 | ## Slider-crank Chrono tutorial (model 0) 16 | ## 17 | ## This model is a 2-body slider-crank consisting of crank and slider bodies. 18 | ## The crank is connected to ground with a revolute joint and the slider is 19 | ## connected to ground through a prismatic joint. A distance constraint models 20 | ## a massless link between the crank and the slider. 21 | ## 22 | ## The mechanism moves under the action of gravity alone, acting in the negative 23 | ## Z direction. 24 | ## 25 | ## The simulation is animated with Irrlicht. 26 | ## 27 | ## ============================================================================= 28 | 29 | import pychrono as chrono 30 | from pychrono import irrlicht as chronoirr 31 | 32 | ## 0. Set the path to the Chrono data folder 33 | chrono.SetChronoDataPath('E:/Repositories/chrono/data/') 34 | 35 | ## 1. Create the physical system that will handle all bodies and constraints. 36 | 37 | ## Specify the gravitational acceleration vector, consistent with the 38 | ## global reference frame having Z up. 39 | system = chrono.ChSystemNSC() 40 | system.SetGravitationalAcceleration(chrono.ChVector3d(0, 0, -9.81)) 41 | 42 | ## 2. Create the rigid bodies of the slider-crank mechanical system. 43 | ## For each body, specify: 44 | ## - a unique identifier 45 | ## - mass and moments of inertia 46 | ## - position and orientation of the (centroidal) body frame 47 | ## - visualization assets (defined with respect to the body frame) 48 | 49 | ## Ground 50 | ground = chrono.ChBody() 51 | system.AddBody(ground) 52 | ground.SetIdentifier(-1) 53 | ground.SetName("ground") 54 | ground.SetFixed(True) 55 | 56 | cyl_g = chrono.ChVisualShapeCylinder(0.03, 0.4) 57 | cyl_g.SetColor(chrono.ChColor(0.6, 0.6, 0.2)) 58 | ground.AddVisualShape(cyl_g) 59 | 60 | ## Crank 61 | crank = chrono.ChBody() 62 | system.AddBody(crank) 63 | crank.SetIdentifier(1) 64 | crank.SetName("crank") 65 | crank.SetMass(1.0) 66 | crank.SetInertiaXX(chrono.ChVector3d(0.005, 0.1, 0.1)) 67 | crank.SetPos(chrono.ChVector3d(-1, 0, 0)) 68 | crank.SetRot(chrono.ChQuaterniond(1, 0, 0, 0)) 69 | 70 | box_c = chrono.ChVisualShapeBox(1.9, 0.1, 0.1) 71 | crank.AddVisualShape(box_c) 72 | 73 | cyl_c = chrono.ChVisualShapeCylinder(0.05, 0.2) 74 | crank.AddVisualShape(cyl_c, chrono.ChFramed(chrono.ChVector3d(1, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2))) 75 | 76 | sph_c = chrono.ChVisualShapeSphere(0.05) 77 | sph_c.SetColor(chrono.ChColor(0.6, 0.2, 0.2)) 78 | crank.AddVisualShape(sph_c, chrono.ChFramed(chrono.ChVector3d(-1, 0, 0))) 79 | 80 | ## Slider 81 | slider = chrono.ChBody() 82 | system.AddBody(slider) 83 | slider.SetIdentifier(2) 84 | slider.SetName("slider") 85 | slider.SetMass(1.0) 86 | slider.SetInertiaXX(chrono.ChVector3d(0.05, 0.05, 0.05)) 87 | slider.SetPos(chrono.ChVector3d(2, 0, 0)) 88 | slider.SetRot(chrono.ChQuaterniond(1, 0, 0, 0)) 89 | 90 | box_s = chrono.ChVisualShapeBox(0.4, 0.2, 0.2) 91 | box_s.SetColor(chrono.ChColor(0.2, 0.2, 0.6)) 92 | slider.AddVisualShape(box_s) 93 | 94 | ## 3. Create joint constraints. 95 | ## All joint frames are specified in the global frame. 96 | 97 | ## Define two quaternions representing: 98 | ## - a rotation of -90 degrees around x (z2y) 99 | ## - a rotation of +90 degrees around y (z2x) 100 | z2y = chrono.ChQuaterniond() 101 | z2x = chrono.ChQuaterniond() 102 | z2y.SetFromAngleAxis(-chrono.CH_PI / 2, chrono.ChVector3d(1, 0, 0)) 103 | z2x.SetFromAngleAxis(chrono.CH_PI / 2, chrono.ChVector3d(0, 1, 0)) 104 | 105 | ## Revolute joint between ground and crank. 106 | ## The rotational axis of a revolute joint is along the Z axis of the 107 | ## specified joint coordinate frame. Here, we apply the 'z2y' rotation to 108 | ## align it with the Y axis of the global reference frame. 109 | revolute_ground_crank = chrono.ChLinkLockRevolute() 110 | revolute_ground_crank.SetName("revolute_ground_crank") 111 | revolute_ground_crank.Initialize(ground, crank, chrono.ChFramed(chrono.ChVector3d(0, 0, 0), z2y)) 112 | system.AddLink(revolute_ground_crank) 113 | 114 | ## Prismatic joint between ground and slider. 115 | ## The translational axis of a prismatic joint is along the Z axis of the 116 | ## specified joint coordinate system. Here, we apply the 'z2x' rotation to 117 | ## align it with the X axis of the global reference frame. 118 | prismatic_ground_slider = chrono.ChLinkLockPrismatic() 119 | prismatic_ground_slider.SetName("prismatic_ground_slider") 120 | prismatic_ground_slider.Initialize(ground, slider, chrono.ChFramed(chrono.ChVector3d(2, 0, 0), z2x)) 121 | system.AddLink(prismatic_ground_slider) 122 | 123 | ## Distance constraint between crank and slider. 124 | ## We provide the points on the two bodies in the global reference frame. 125 | ## By default the imposed distance is calculated automatically as the distance 126 | ## between these two points in the initial configuration. 127 | dist_crank_slider = chrono.ChLinkDistance() 128 | dist_crank_slider.SetName("dist_crank_slider") 129 | dist_crank_slider.Initialize(crank, slider, False, chrono.ChVector3d(-2, 0, 0), chrono.ChVector3d(2, 0, 0)) 130 | system.AddLink(dist_crank_slider) 131 | 132 | ## 4. Write the system hierarchy to the console (default log output destination) 133 | ####system.ShowHierarchy(chrono.GetLog()) 134 | 135 | ## 5. Prepare visualization with Irrlicht 136 | ## Note that Irrlicht uses left-handed frames with Y up. 137 | 138 | ## Create the Irrlicht application and set-up the camera. 139 | vis = chronoirr.ChVisualSystemIrrlicht() 140 | vis.AttachSystem(system) 141 | vis.SetWindowSize(1024,768) 142 | vis.SetWindowTitle('Slider-Crank Demo 0') 143 | vis.SetCameraVertical(chrono.CameraVerticalDir_Z) 144 | vis.Initialize() 145 | vis.AddLogo(chrono.GetChronoDataFile('logo_pychrono_alpha.png')) 146 | vis.AddSkyBox() 147 | vis.AddCamera(chrono.ChVector3d(2, -5, 0), chrono.ChVector3d(2, 0, 0)) 148 | vis.AddTypicalLights() 149 | 150 | ## 6. Perform the simulation. 151 | step_size = 0.01 152 | realtime_timer = chrono.ChRealtimeStepTimer() 153 | 154 | while vis.Run(): 155 | vis.BeginScene() 156 | 157 | # Render Chrono item assets 158 | vis.Render() 159 | 160 | ## Render the distance constraint 161 | chronoirr.drawSegment( 162 | vis, 163 | dist_crank_slider.GetEndPoint1Abs(), 164 | dist_crank_slider.GetEndPoint2Abs(), 165 | chrono.ChColor(0.8, 0.1, 0), True) 166 | 167 | ## Draw an XZ grid at the global origin to add in visualization 168 | chronoirr.drawGrid( 169 | vis, 1, 1, 20, 20, 170 | chrono.ChCoordsysd(chrono.ChVector3d(0, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2)), 171 | chrono.ChColor(0.4, 0.7, 0.4), True) 172 | chronoirr.drawAllCOGs(vis, 1) 173 | 174 | vis.EndScene() 175 | 176 | ## Advance simulation by one step 177 | system.DoStepDynamics(step_size) 178 | 179 | # Spin in place for real time to catch up 180 | realtime_timer.Spin(step_size) 181 | -------------------------------------------------------------------------------- /PyChrono/slider-crank/slider_crank_1.py: -------------------------------------------------------------------------------- 1 | ## ============================================================================= 2 | ## PROJECT CHRONO - http:##projectchrono.org 3 | ## 4 | ## Copyright (c) 2014 projectchrono.org 5 | ## All right reserved. 6 | ## 7 | ## Use of this source code is governed by a BSD-style license that can be found 8 | ## in the LICENSE file at the top level of the distribution and at 9 | ## http://projectchrono.org/license-chrono.txt. 10 | ## 11 | ## ============================================================================= 12 | ## Author: Simone Benatti 13 | ## ============================================================================= 14 | ## 15 | ## Slider-crank Chrono tutorial (model 1) 16 | ## 17 | ## This model is a 3-body slider-crank consisting of crank, slider and connecting 18 | ## rod bodies. The crank is connected to ground with a revolute joint and the 19 | ## slider is connected to ground through a prismatic joint. The connecting rod 20 | ## connects to the crank through a spherical joint and to the slider through a 21 | ## universal joint. 22 | ## 23 | ## The crank body is driven at constant angular speed, under the action of gravity, 24 | ## acting in the negative Z direction. 25 | ## 26 | ## The simulation is animated with Irrlicht. 27 | ## 28 | ## ============================================================================= 29 | 30 | import pychrono as chrono 31 | from pychrono import irrlicht as chronoirr 32 | 33 | ## 0. Set the path to the Chrono data folder 34 | chrono.SetChronoDataPath('E:/Repositories/chrono/data/') 35 | 36 | ## 1. Create the physical system that will handle all bodies and constraints. 37 | 38 | ## Specify the gravitational acceleration vector, consistent with the 39 | ## global reference frame having Z up. 40 | system = chrono.ChSystemNSC() 41 | system.SetGravitationalAcceleration(chrono.ChVector3d(0, 0, -9.81)) 42 | 43 | ## 2. Create the rigid bodies of the slider-crank mechanical system. 44 | ## For each body, specify: 45 | ## - a unique identifier 46 | ## - mass and moments of inertia 47 | ## - position and orientation of the (centroidal) body frame 48 | ## - visualization assets (defined with respect to the body frame) 49 | 50 | ## Ground 51 | ground = chrono.ChBody() 52 | system.AddBody(ground) 53 | ground.SetIdentifier(-1) 54 | ground.SetName("ground") 55 | ground.SetFixed(True) 56 | 57 | cyl_g = chrono.ChVisualShapeCylinder(0.03, 0.4) 58 | cyl_g.SetColor(chrono.ChColor(0.6, 0.6, 0.2)) 59 | ground.AddVisualShape(cyl_g) 60 | 61 | ## Crank 62 | crank = chrono.ChBody() 63 | system.AddBody(crank) 64 | crank.SetIdentifier(1) 65 | crank.SetName("crank") 66 | crank.SetMass(1.0) 67 | crank.SetInertiaXX(chrono.ChVector3d(0.005, 0.1, 0.1)) 68 | crank.SetPos(chrono.ChVector3d(-1, 0, 0)) 69 | crank.SetRot(chrono.ChQuaterniond(1, 0, 0, 0)) 70 | 71 | box_c = chrono.ChVisualShapeBox(1.9, 0.1, 0.1) 72 | crank.AddVisualShape(box_c) 73 | 74 | cyl_c = chrono.ChVisualShapeCylinder(0.05, 0.2) 75 | crank.AddVisualShape(cyl_c, chrono.ChFramed(chrono.ChVector3d(1, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2))) 76 | 77 | sph_c = chrono.ChVisualShapeSphere(0.05) 78 | sph_c.SetColor(chrono.ChColor(0.6, 0.2, 0.2)) 79 | crank.AddVisualShape(sph_c, chrono.ChFramed(chrono.ChVector3d(-1, 0, 0))) 80 | 81 | ## Slider 82 | slider = chrono.ChBody() 83 | system.AddBody(slider) 84 | slider.SetIdentifier(2) 85 | slider.SetName("slider") 86 | slider.SetMass(1.0) 87 | slider.SetInertiaXX(chrono.ChVector3d(0.05, 0.05, 0.05)) 88 | slider.SetPos(chrono.ChVector3d(2, 0, 0)) 89 | slider.SetRot(chrono.ChQuaterniond(1, 0, 0, 0)) 90 | 91 | box_s = chrono.ChVisualShapeBox(0.4, 0.2, 0.2) 92 | box_s.SetColor(chrono.ChColor(0.2, 0.2, 0.6)) 93 | slider.AddVisualShape(box_s) 94 | 95 | #### ------------------------------------------------------------------------- 96 | #### EXERCISE 1.1 97 | #### Create a connecting rod body to replace the distance constraint. 98 | #### This body should have: 99 | #### mass: 0.5 100 | #### moments of inertia: I_xx = 0.005, I_yy = 0.1, I_zz = 0.1 101 | #### visualization: a green box with width and height 0.1 102 | #### ------------------------------------------------------------------------- 103 | 104 | 105 | 106 | 107 | ## 3. Create joint constraints. 108 | ## All joint frames are specified in the global frame. 109 | 110 | ## Define two quaternions representing: 111 | ## - a rotation of -90 degrees around x (z2y) 112 | ## - a rotation of +90 degrees around y (z2x) 113 | z2y = chrono.ChQuaterniond() 114 | z2x = chrono.ChQuaterniond() 115 | z2y.SetFromAngleX(-chrono.CH_PI / 2) 116 | z2x.SetFromAngleY(chrono.CH_PI / 2) 117 | 118 | #### ------------------------------------------------------------------------- 119 | #### EXERCISE 1.2 120 | #### Replace the revolute joint between ground and crank with a 121 | #### ChLinkMotorRotationSpeed element and enforce constant angular speed of 122 | #### 90 degrees/s. 123 | #### ------------------------------------------------------------------------- 124 | 125 | 126 | 127 | 128 | ## Prismatic joint between ground and slider. 129 | ## The translational axis of a prismatic joint is along the Z axis of the 130 | ## specified joint coordinate system. Here, we apply the 'z2x' rotation to 131 | ## align it with the X axis of the global reference frame. 132 | prismatic_ground_slider = chrono.ChLinkLockPrismatic() 133 | prismatic_ground_slider.SetName("prismatic_ground_slider") 134 | prismatic_ground_slider.Initialize(ground, slider, chrono.ChFramed(chrono.ChVector3d(2, 0, 0), z2x)) 135 | system.AddLink(prismatic_ground_slider) 136 | 137 | #### ------------------------------------------------------------------------- 138 | #### EXERCISE 1.3 139 | #### Replace the distance constraint with joints connecting the rod to the 140 | #### crank (use ChLinkLockSpherical) and to the slider (ChLinkUniversal). The 141 | #### universal joint's cross should be aligned with the Z and Y global axes. 142 | #### ------------------------------------------------------------------------- 143 | 144 | 145 | 146 | 147 | ## 4. Write the system hierarchy to the console (default log output destination) 148 | ####system.ShowHierarchy(chrono.GetLog()) 149 | 150 | 151 | ## 5. Prepare visualization with Irrlicht 152 | ## Note that Irrlicht uses left-handed frames with Y up. 153 | 154 | ## Create the Irrlicht application and set-up the camera. 155 | vis = chronoirr.ChVisualSystemIrrlicht() 156 | vis.AttachSystem(system) 157 | vis.SetWindowSize(1024,768) 158 | vis.SetWindowTitle('Slider-Crank Demo 1') 159 | vis.SetCameraVertical(chrono.CameraVerticalDir_Z) 160 | vis.Initialize() 161 | vis.AddLogo(chrono.GetChronoDataFile('logo_pychrono_alpha.png')) 162 | vis.AddSkyBox() 163 | vis.AddCamera(chrono.ChVector3d(2, -5, 0), chrono.ChVector3d(2, 0, 0)) 164 | vis.AddTypicalLights() 165 | 166 | ## 6. Perform the simulation. 167 | 168 | ## Specify the step-size. 169 | step_size = 0.01 170 | realtime_timer = chrono.ChRealtimeStepTimer() 171 | 172 | while (vis.Run()): 173 | vis.BeginScene() 174 | 175 | # Render Chrono item assets 176 | vis.Render() 177 | 178 | ## Draw an XZ grid at the global origin to add in visualization 179 | chronoirr.drawGrid( 180 | vis, 1, 1, 20, 20, 181 | chrono.ChCoordsysd(chrono.ChVector3d(0, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2)), 182 | chrono.ChColor(0.4, 0.7, 0.4), True) 183 | chronoirr.drawAllCOGs(vis, 1) 184 | 185 | vis.EndScene() 186 | 187 | ## Advance simulation by one step 188 | system.DoStepDynamics(step_size) 189 | 190 | # Spin in place for real time to catch up 191 | realtime_timer.Spin(step_size) 192 | -------------------------------------------------------------------------------- /PyChrono/wheeled_vehicle/wheeled_vehicle.py: -------------------------------------------------------------------------------- 1 | import pychrono as chrono 2 | import pychrono.vehicle as veh 3 | import pychrono.irrlicht as chronoirr 4 | import os 5 | import math as m 6 | 7 | 8 | def AddMovingObstacles(system) : 9 | # Create contact material, of appropriate type. Use default properties 10 | material = None 11 | if (NSC_SMC == chrono.ChContactMethod_NSC) : 12 | matNSC = chrono.ChContactMaterialNSC() 13 | #Change NSC material properties as desired 14 | material = matNSC 15 | elif (NSC_SMC == chrono.ChContactMethod_SMC) : 16 | matSMC = chrono.ChContactMaterialSMC() 17 | # Change SMC material properties as desired 18 | material = matSMC 19 | else: 20 | raise("Invalid Contact Method") 21 | 22 | sizeX = 300 23 | sizeY = 300 24 | height = 0 25 | numObstacles = 5 26 | 27 | for i in range(numObstacles) : 28 | o_sizeX = 1.0 + 3.0 * chrono.ChRandom.Get() 29 | o_sizeY = 0.3 + 0.4 * chrono.ChRandom.Get() 30 | o_sizeZ = 0.2 + 0.2 * chrono.ChRandom.Get() 31 | obstacle = chrono.ChBodyEasyBox(o_sizeX, o_sizeY, o_sizeZ, 2000.0, True, True, material) 32 | 33 | o_posX = chrono.ChRandom.Get() * 0.2 * sizeX 34 | o_posY = chrono.ChRandom.Get() * 0.2 * sizeY 35 | o_posZ = height + 4 36 | obstacle.SetPos(chrono.ChVector3d(o_posX, o_posY, o_posZ)) 37 | obstacle.SetRot(chrono.QuatFromAngleX(chrono.CH_PI / 3) * chrono.QuatFromAngleY(chrono.CH_PI / 6)) 38 | 39 | system.AddBody(obstacle) 40 | 41 | def AddFixedObstacles(system) : 42 | # Create contact material, of appropriate type. Use default properties 43 | material = None 44 | if (NSC_SMC == chrono.ChContactMethod_NSC) : 45 | matNSC = chrono.ChContactMaterialNSC() 46 | #Change NSC material properties as desired 47 | material = matNSC 48 | elif (NSC_SMC == chrono.ChContactMethod_SMC) : 49 | matSMC = chrono.ChContactMaterialSMC() 50 | # Change SMC material properties as desired 51 | material = matSMC 52 | else: 53 | raise("Unvalid Contact Method") 54 | radius = 3; 55 | length = 10; 56 | obstacle = chrono.ChBodyEasyCylinder(chrono.ChAxis_Y, radius, length, 2000, True, True, material) 57 | 58 | obstacle.SetPos(chrono.ChVector3d(-20, 0, -2.7)) 59 | obstacle.SetFixed(True) 60 | 61 | system.AddBody(obstacle) 62 | 63 | for i in range(4) : 64 | stoneslab = chrono.ChBodyEasyBox(1.0, 5.0, 0.5, 2000, True, True, material) 65 | stoneslab.SetPos(chrono.ChVector3d(-1.2 * i + 22, -1.5, -0.25)) 66 | 67 | stoneslab.SetRot(chrono.QuatFromAngleAxis(15 * chrono.CH_DEG_TO_RAD, chrono.VECT_Y)) 68 | stoneslab.SetFixed(True); 69 | system.AddBody(stoneslab); 70 | 71 | 72 | def main(): 73 | # ---------------------- 74 | # Set path to data files 75 | # ---------------------- 76 | 77 | # Path to Chrono data files (textures, etc.) 78 | print(CHRONO_DATA_DIR) 79 | chrono.SetChronoDataPath(CHRONO_DATA_DIR); 80 | 81 | # Path to the data files for this vehicle (JSON specification files) 82 | veh.SetDataPath("./data/") 83 | 84 | # -------------------------- 85 | # Create the various modules 86 | # -------------------------- 87 | 88 | # Create and initialize the vehicle system 89 | vehicle = veh.WheeledVehicle(veh.GetDataFile(vehicle_file), NSC_SMC) 90 | 91 | vehicle.Initialize(chrono.ChCoordsysd(initLoc, initRot)) 92 | 93 | vehicle.SetSuspensionVisualizationType(veh.VisualizationType_PRIMITIVES) 94 | vehicle.SetSteeringVisualizationType(veh.VisualizationType_PRIMITIVES) 95 | vehicle.SetWheelVisualizationType(veh.VisualizationType_NONE) 96 | 97 | # Create the terrain 98 | terrain = veh.RigidTerrain(vehicle.GetSystem(), veh.GetDataFile(rigidterrain_file)) 99 | terrain.Initialize() 100 | 101 | AddFixedObstacles(vehicle.GetSystem()) 102 | AddMovingObstacles(vehicle.GetSystem()) 103 | 104 | # Create and initialize the powertrain system 105 | engine = veh.ReadEngineJSON(veh.GetDataFile(engine_file)) 106 | transmission = veh.ReadTransmissionJSON(veh.GetDataFile(transmission_file)) 107 | powertrain = veh.ChPowertrainAssembly(engine, transmission) 108 | vehicle.InitializePowertrain(powertrain) 109 | 110 | # Create and initialize the tires 111 | for axle in vehicle.GetAxles() : 112 | tireL = veh.RigidTire(veh.GetDataFile(rigidtire_file)) 113 | tireR = veh.RigidTire(veh.GetDataFile(rigidtire_file)) 114 | vehicle.InitializeTire(tireL, axle.m_wheels[0], veh.VisualizationType_MESH) 115 | vehicle.InitializeTire(tireR, axle.m_wheels[1], veh.VisualizationType_MESH) 116 | 117 | # Set collision system 118 | vehicle.GetSystem().SetCollisionSystemType(chrono.ChCollisionSystem.Type_BULLET) 119 | 120 | # Create the Irrlicht vehicle application 121 | vis = veh.ChWheeledVehicleVisualSystemIrrlicht() 122 | vis.SetWindowTitle('Vehicle demo') 123 | vis.SetWindowSize(1280, 1024) 124 | vis.SetChaseCamera(chrono.ChVector3d(0.0, 0.0, 1.75), 6.0, 0.5) 125 | vis.Initialize() 126 | vis.AddLogo(chrono.GetChronoDataFile('logo_pychrono_alpha.png')) 127 | vis.AddLightDirectional() 128 | vis.AddSkyBox() 129 | vis.AttachVehicle(vehicle) 130 | 131 | # Create the driver system (interactive) 132 | driver = veh.ChInteractiveDriverIRR(vis) 133 | driver.SetSteeringDelta(0.02) 134 | driver.SetThrottleDelta(0.02) 135 | driver.SetBrakingDelta(0.02) 136 | driver.Initialize() 137 | 138 | # --------------- 139 | # Simulation loop 140 | # --------------- 141 | 142 | # Number of simulation steps between two 3D view render frames 143 | render_steps = m.ceil(render_step_size / step_size) 144 | 145 | #Initialize simulation frame counter and simulation time 146 | time = 0 147 | 148 | vehicle.EnableRealtime(True) 149 | 150 | while vis.Run() : 151 | # Render scene 152 | vis.BeginScene() 153 | vis.Render() 154 | vis.EndScene() 155 | 156 | # Get driver inputs 157 | driver_inputs = driver.GetInputs() 158 | 159 | # Update modules (process inputs from other modules) 160 | time = vehicle.GetSystem().GetChTime() 161 | driver.Synchronize(time) 162 | vehicle.Synchronize(time, driver_inputs, terrain) 163 | terrain.Synchronize(time) 164 | vis.Synchronize(time, driver_inputs) 165 | 166 | # Advance simulation for one timestep for all modules 167 | driver.Advance(step_size) 168 | vehicle.Advance(step_size) 169 | terrain.Advance(step_size) 170 | vis.Advance(step_size) 171 | 172 | return 0 173 | 174 | 175 | # change these paths 176 | vehicle_file = "vehicle/WheeledVehicle.json" 177 | rigidtire_file = "vehicle/RigidTire.json" 178 | engine_file = "vehicle/EngineSimple.json" 179 | transmission_file = "vehicle/AutomaticTransmissionSimpleMap.json" 180 | 181 | CHRONO_DATA_DIR = "E:/Repositories/chrono/data/" 182 | 183 | rigidterrain_file = "terrain/RigidPlane.json" 184 | 185 | povray_output = False 186 | # Initial vehicle position and orientation 187 | initLoc = chrono.ChVector3d(0, 0, 1.0) 188 | initRot = chrono.ChQuaterniond(1, 0, 0, 0) 189 | 190 | # Simulation step size 191 | step_size = 2e-3 192 | 193 | # Time interval between two render frames 194 | render_step_size = 1.0 / 50 # // FPS = 50 195 | 196 | # Point on chassis tracked by the camera 197 | trackPoint = chrono.ChVector3d(0.0, 0.0, 1.75) 198 | 199 | # Contact method 200 | NSC_SMC = chrono.ChContactMethod_NSC 201 | 202 | main() -------------------------------------------------------------------------------- /Chrono/slider_crank/slider_crank_0.cpp: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // PROJECT CHRONO - http://projectchrono.org 3 | // 4 | // Copyright (c) 2014 projectchrono.org 5 | // All right reserved. 6 | // 7 | // Use of this source code is governed by a BSD-style license that can be found 8 | // in the LICENSE file at the top level of the distribution and at 9 | // http://projectchrono.org/license-chrono.txt. 10 | // 11 | // ============================================================================= 12 | // Author: Radu Serban 13 | // ============================================================================= 14 | // 15 | // Slider-crank Chrono tutorial (model 0) 16 | // 17 | // This model is a 2-body slider-crank consisting of crank and slider bodies. 18 | // The crank is connected to ground with a revolute joint and the slider is 19 | // connected to ground through a prismatic joint. A distance constraint models 20 | // a massless link between the crank and the slider. 21 | // 22 | // The mechanism moves under the action of gravity alone, acting in the negative 23 | // Z direction. 24 | // 25 | // The simulation is animated with Irrlicht. 26 | // 27 | // ============================================================================= 28 | 29 | #include 30 | #include 31 | 32 | #include "chrono/physics/ChSystemNSC.h" 33 | #include "chrono/core/ChRealtimeStep.h" 34 | #include "chrono_irrlicht/ChVisualSystemIrrlicht.h" 35 | 36 | using namespace chrono; 37 | using namespace chrono::irrlicht; 38 | using namespace irr; 39 | 40 | int main(int argc, char* argv[]) { 41 | // 0. Set the path to the Chrono data folder 42 | 43 | SetChronoDataPath(CHRONO_DATA_DIR); 44 | 45 | // 1. Create the physical system that will handle all bodies and constraints. 46 | 47 | // Specify the gravitational acceleration vector, consistent with the 48 | // global reference frame having Z up. 49 | ChSystemNSC system; 50 | system.SetGravitationalAcceleration(ChVector3d(0, 0, -9.81)); 51 | 52 | // 2. Create the rigid bodies of the slider-crank mechanical system. 53 | // For each body, specify: 54 | // - a unique identifier 55 | // - mass and moments of inertia 56 | // - position and orientation of the (centroidal) body frame 57 | // - visualization assets (defined with respect to the body frame) 58 | 59 | // Ground 60 | auto ground = chrono_types::make_shared(); 61 | system.AddBody(ground); 62 | ground->SetName("ground"); 63 | ground->SetFixed(true); 64 | 65 | auto cyl_g = chrono_types::make_shared(0.03, 0.4); 66 | ground->AddVisualShape(cyl_g, ChFrame<>(VNULL, QuatFromAngleX(CH_PI_2))); 67 | 68 | // Crank 69 | auto crank = chrono_types::make_shared(); 70 | system.AddBody(crank); 71 | crank->SetName("crank"); 72 | crank->SetMass(1.0); 73 | crank->SetInertiaXX(ChVector3d(0.005, 0.1, 0.1)); 74 | crank->SetPos(ChVector3d(-1, 0, 0)); 75 | crank->SetRot(ChQuaternion<>(1, 0, 0, 0)); 76 | 77 | auto box_c = chrono_types::make_shared(1.9, 0.1, 0.1); 78 | box_c->SetColor(ChColor(0.6f, 0.2f, 0.2f)); 79 | crank->AddVisualShape(box_c); 80 | 81 | auto cyl_c = chrono_types::make_shared(0.05, 0.2); 82 | cyl_c->SetColor(ChColor(0.6f, 0.2f, 0.2f)); 83 | crank->AddVisualShape(cyl_c, ChFrame<>(ChVector3d(1, 0, 0), QuatFromAngleX(CH_PI_2))); 84 | 85 | auto sph_c = chrono_types::make_shared(0.05); 86 | sph_c->SetColor(ChColor(0.6f, 0.2f, 0.2f)); 87 | crank->AddVisualShape(sph_c, ChFrame<>(ChVector3d(-1, 0, 0))); 88 | 89 | // Slider 90 | auto slider = chrono_types::make_shared(); 91 | system.AddBody(slider); 92 | slider->SetName("slider"); 93 | slider->SetMass(1.0); 94 | slider->SetInertiaXX(ChVector3d(0.05, 0.05, 0.05)); 95 | slider->SetPos(ChVector3d(2, 0, 0)); 96 | slider->SetRot(ChQuaternion<>(1, 0, 0, 0)); 97 | 98 | auto box_s = chrono_types::make_shared(0.4, 0.2, 0.2); 99 | box_s->SetColor(ChColor(0.2f, 0.2f, 0.6f)); 100 | slider->AddVisualShape(box_s); 101 | 102 | // 3. Create joint constraints. 103 | // All joint frames are specified in the global frame. 104 | 105 | // Define two quaternions representing: 106 | // - a rotation of -90 degrees around x (z2y) 107 | // - a rotation of +90 degrees around y (z2x) 108 | ChQuaternion<> z2y; 109 | ChQuaternion<> z2x; 110 | z2y.SetFromAngleAxis(-CH_PI / 2, ChVector3d(1, 0, 0)); 111 | z2x.SetFromAngleAxis(CH_PI / 2, ChVector3d(0, 1, 0)); 112 | 113 | // Revolute joint between ground and crank. 114 | // The rotational axis of a revolute joint is along the Z axis of the 115 | // specified joint coordinate frame. Here, we apply the 'z2y' rotation to 116 | // align it with the Y axis of the global reference frame. 117 | auto revolute_ground_crank = chrono_types::make_shared(); 118 | revolute_ground_crank->SetName("revolute_ground_crank"); 119 | revolute_ground_crank->Initialize(ground, crank, ChFrame<>(ChVector3d(0, 0, 0), z2y)); 120 | system.AddLink(revolute_ground_crank); 121 | 122 | // Prismatic joint between ground and slider. 123 | // The translational axis of a prismatic joint is along the Z axis of the 124 | // specified joint coordinate system. Here, we apply the 'z2x' rotation to 125 | // align it with the X axis of the global reference frame. 126 | auto prismatic_ground_slider = chrono_types::make_shared(); 127 | prismatic_ground_slider->SetName("prismatic_ground_slider"); 128 | prismatic_ground_slider->Initialize(ground, slider, ChFrame<>(ChVector3d(2, 0, 0), z2x)); 129 | system.AddLink(prismatic_ground_slider); 130 | 131 | // Distance constraint between crank and slider. 132 | // We provide the points on the two bodies in the global reference frame. 133 | // By default the imposed distance is calculated automatically as the distance 134 | // between these two points in the initial configuration. 135 | auto dist_crank_slider = chrono_types::make_shared(); 136 | dist_crank_slider->SetName("dist_crank_slider"); 137 | dist_crank_slider->Initialize(crank, slider, false, ChVector3d(-2, 0, 0), ChVector3d(2, 0, 0)); 138 | system.AddLink(dist_crank_slider); 139 | 140 | // 4. Write the system hierarchy to the console (default log output destination) 141 | system.ShowHierarchy(std::cout); 142 | 143 | // 5. Prepare visualization with Irrlicht 144 | // Note that Irrlicht uses left-handed frames with Y up. 145 | 146 | // Create the Irrlicht application and set-up the camera. 147 | auto vis = chrono_types::make_shared(); 148 | vis->SetWindowSize(800, 600); 149 | vis->SetCameraVertical(CameraVerticalDir::Z); 150 | vis->SetWindowTitle("Slider-Crank Demo 0"); 151 | vis->Initialize(); 152 | vis->AddLogo(); 153 | vis->AddSkyBox(); 154 | vis->AddCamera(ChVector3d(2, -5, 0), ChVector3d(2, 0, 0)); 155 | vis->AddTypicalLights(); 156 | vis->AttachSystem(&system); 157 | 158 | // 6. Perform the simulation. 159 | 160 | ChRealtimeStepTimer realtime_timer; 161 | while (vis->Run()) { 162 | // Initialize the graphical scene. 163 | vis->BeginScene(); 164 | 165 | // Render all visualization objects. 166 | vis->Render(); 167 | 168 | // Render the distance constraint. 169 | tools::drawSegment(vis.get(), dist_crank_slider->GetEndPoint1Abs(), 170 | dist_crank_slider->GetEndPoint2Abs(), ChColor(0.8f, 0.2f, 0), true); 171 | 172 | // Draw an XZ grid at the global origin to add in visualization. 173 | tools::drawGrid(vis.get(), 1, 1, 20, 20, ChCoordsys<>(ChVector3d(0.01, 0, 0.01), QuatFromAngleX(CH_PI_2)), 174 | ChColor(0.6f, 0.6f, 0.6f), true); 175 | tools::drawAllCOGs(vis.get(), 1.0); 176 | 177 | // Finalize the graphical scene. 178 | vis->EndScene(); 179 | 180 | // Advance simulation by one step. 181 | system.DoStepDynamics(0.01); 182 | realtime_timer.Spin(0.01); 183 | } 184 | 185 | return 0; 186 | } 187 | -------------------------------------------------------------------------------- /Chrono/slider_crank/slider_crank_1.cpp: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // PROJECT CHRONO - http://projectchrono.org 3 | // 4 | // Copyright (c) 2014 projectchrono.org 5 | // All right reserved. 6 | // 7 | // Use of this source code is governed by a BSD-style license that can be found 8 | // in the LICENSE file at the top level of the distribution and at 9 | // http://projectchrono.org/license-chrono.txt. 10 | // 11 | // ============================================================================= 12 | // Author: Radu Serban 13 | // ============================================================================= 14 | // 15 | // Slider-crank Chrono tutorial (model 1) 16 | // 17 | // This model is a 3-body slider-crank consisting of crank, slider and connecting 18 | // rod bodies. The crank is connected to ground with a revolute joint and the 19 | // slider is connected to ground through a prismatic joint. The connecting rod 20 | // connects to the crank through a spherical joint and to the slider through a 21 | // universal joint. 22 | // 23 | // The crank body is driven at constant angular speed, under the action of gravity, 24 | // acting in the negative Z direction. 25 | // 26 | // The simulation is animated with Irrlicht. 27 | // 28 | // ============================================================================= 29 | 30 | #include 31 | #include 32 | 33 | #include "chrono/physics/ChSystemNSC.h" 34 | #include "chrono/core/ChRealtimeStep.h" 35 | #include "chrono_irrlicht/ChVisualSystemIrrlicht.h" 36 | 37 | using namespace chrono; 38 | using namespace chrono::irrlicht; 39 | using namespace irr; 40 | 41 | int main(int argc, char* argv[]) { 42 | // 0. Set the path to the Chrono data folder 43 | 44 | SetChronoDataPath(CHRONO_DATA_DIR); 45 | 46 | // 1. Create the physical system that will handle all bodies and constraints. 47 | 48 | // Specify the gravitational acceleration vector, consistent with the 49 | // global reference frame having Z up. 50 | ChSystemNSC system; 51 | system.SetGravitationalAcceleration(ChVector3d(0, 0, -9.81)); 52 | 53 | // 2. Create the rigid bodies of the slider-crank mechanical system. 54 | // For each body, specify: 55 | // - a unique identifier 56 | // - mass and moments of inertia 57 | // - position and orientation of the (centroidal) body frame 58 | // - visualization assets (defined with respect to the body frame) 59 | 60 | // Ground 61 | auto ground = chrono_types::make_shared(); 62 | system.AddBody(ground); 63 | ground->SetName("ground"); 64 | ground->SetFixed(true); 65 | 66 | auto cyl_g = chrono_types::make_shared(0.03, 0.4); 67 | ground->AddVisualShape(cyl_g, ChFrame<>(VNULL, QuatFromAngleX(CH_PI_2))); 68 | 69 | // Crank 70 | auto crank = chrono_types::make_shared(); 71 | system.AddBody(crank); 72 | crank->SetName("crank"); 73 | crank->SetMass(1.0); 74 | crank->SetInertiaXX(ChVector3d(0.005, 0.1, 0.1)); 75 | crank->SetPos(ChVector3d(-1, 0, 0)); 76 | crank->SetRot(ChQuaternion<>(1, 0, 0, 0)); 77 | 78 | auto box_c = chrono_types::make_shared(1.9, 0.1, 0.1); 79 | box_c->SetColor(ChColor(0.6f, 0.2f, 0.2f)); 80 | crank->AddVisualShape(box_c); 81 | 82 | auto cyl_c = chrono_types::make_shared(0.05, 0.2); 83 | cyl_c->SetColor(ChColor(0.6f, 0.2f, 0.2f)); 84 | crank->AddVisualShape(cyl_c, ChFrame<>(ChVector3d(1, 0, 0), QuatFromAngleX(CH_PI_2))); 85 | 86 | auto sph_c = chrono_types::make_shared(0.05); 87 | sph_c->SetColor(ChColor(0.6f, 0.2f, 0.2f)); 88 | crank->AddVisualShape(sph_c, ChFrame<>(ChVector3d(-1, 0, 0))); 89 | 90 | // Slider 91 | auto slider = chrono_types::make_shared(); 92 | system.AddBody(slider); 93 | slider->SetName("slider"); 94 | slider->SetMass(1.0); 95 | slider->SetInertiaXX(ChVector3d(0.05, 0.05, 0.05)); 96 | slider->SetPos(ChVector3d(2, 0, 0)); 97 | slider->SetRot(ChQuaternion<>(1, 0, 0, 0)); 98 | 99 | auto box_s = chrono_types::make_shared(0.4, 0.2, 0.2); 100 | box_s->SetColor(ChColor(0.2f, 0.2f, 0.6f)); 101 | slider->AddVisualShape(box_s); 102 | 103 | //// ------------------------------------------------------------------------- 104 | //// EXERCISE 1.1 105 | //// Create a connecting rod body to replace the distance constraint. 106 | //// This body should have: 107 | //// mass: 0.5 108 | //// moments of inertia: I_xx = 0.005, I_yy = 0.1, I_zz = 0.1 109 | //// visualization: a green box with width and height 0.1 110 | //// ------------------------------------------------------------------------- 111 | 112 | // 3. Create joint constraints. 113 | // All joint frames are specified in the global frame. 114 | 115 | // Define two quaternions representing: 116 | // - a rotation of -90 degrees around x (z2y) 117 | // - a rotation of +90 degrees around y (z2x) 118 | ChQuaternion<> z2y; 119 | ChQuaternion<> z2x; 120 | z2y.SetFromAngleAxis(-CH_PI / 2, ChVector3d(1, 0, 0)); 121 | z2x.SetFromAngleAxis(CH_PI / 2, ChVector3d(0, 1, 0)); 122 | 123 | //// ------------------------------------------------------------------------- 124 | //// EXERCISE 1.2 125 | //// Replace the revolute joint between ground and crank with a 126 | //// ChLinkMotorRotationSpeed element and enforce constant angular speed of 127 | //// 90 degrees/s. 128 | //// ------------------------------------------------------------------------- 129 | 130 | // Prismatic joint between ground and slider. 131 | // The translational axis of a prismatic joint is along the Z axis of the 132 | // specified joint coordinate system. Here, we apply the 'z2x' rotation to 133 | // align it with the X axis of the global reference frame. 134 | auto prismatic_ground_slider = chrono_types::make_shared(); 135 | prismatic_ground_slider->SetName("prismatic_ground_slider"); 136 | prismatic_ground_slider->Initialize(ground, slider, ChFrame<>(ChVector3d(2, 0, 0), z2x)); 137 | system.AddLink(prismatic_ground_slider); 138 | 139 | //// ------------------------------------------------------------------------- 140 | //// EXERCISE 1.3 141 | //// Replace the distance constraint with joints connecting the rod to the 142 | //// crank (use ChLinkLockSpherical) and to the slider (ChLinkUniversal). The 143 | //// universal joint's cross should be aligned with the Z and Y global axes. 144 | //// ------------------------------------------------------------------------- 145 | 146 | // 4. Write the system hierarchy to the console (default log output destination) 147 | system.ShowHierarchy(std::cout); 148 | 149 | // 5. Prepare visualization with Irrlicht 150 | // Note that Irrlicht uses left-handed frames with Y up. 151 | 152 | // Create the Irrlicht application and set-up the camera. 153 | auto vis = chrono_types::make_shared(); 154 | vis->SetWindowSize(800, 600); 155 | vis->SetCameraVertical(CameraVerticalDir::Z); 156 | vis->SetWindowTitle("Slider-Crank Demo 1"); 157 | vis->Initialize(); 158 | vis->AddLogo(); 159 | vis->AddSkyBox(); 160 | vis->AddCamera(ChVector3d(2, -5, 0), ChVector3d(2, 0, 0)); 161 | vis->AddTypicalLights(); 162 | vis->AttachSystem(&system); 163 | 164 | // 6. Perform the simulation. 165 | 166 | ChRealtimeStepTimer realtime_timer; 167 | while (vis->Run()) { 168 | // Initialize the graphical scene. 169 | vis->BeginScene(); 170 | 171 | // Render all visualization objects. 172 | vis->Render(); 173 | 174 | // Draw an XZ grid at the global origin to add in visualization. 175 | tools::drawGrid(vis.get(), 1, 1, 20, 20, ChCoordsys<>(ChVector3d(0.01, 0, 0.01), QuatFromAngleX(CH_PI_2)), 176 | ChColor(0.6f, 0.6f, 0.6f), true); 177 | tools::drawAllCOGs(vis.get(), 1.0); 178 | 179 | // Finalize the graphical scene. 180 | vis->EndScene(); 181 | 182 | // Advance simulation by one step. 183 | system.DoStepDynamics(0.01); 184 | realtime_timer.Spin(0.01); 185 | } 186 | 187 | return 0; 188 | } 189 | -------------------------------------------------------------------------------- /PyChrono/FEA/FEA_cable_collide_2.py: -------------------------------------------------------------------------------- 1 | # ============================================================================= 2 | # PROJECT CHRONO - http:#projectchrono.org 3 | # 4 | # Copyright (c) 2014 projectchrono.org 5 | # All right reserved. 6 | # 7 | # Use of this source code is governed by a BSD-style license that can be found 8 | # in the LICENSE file at the top level of the distribution and at 9 | # http:#projectchrono.org/license-chrono.txt. 10 | # 11 | # ============================================================================= 12 | # Author: Simone Benatti 13 | # ============================================================================= 14 | # 15 | # Create a falling and colliding cable using FEA module (FEA tutorial n.2) 16 | # 17 | # This model is made with N elements of ChElementBeamEuler type. They are 18 | # added to a ChMesh and then the first cable is connected to the absolute 19 | # reference using a joint. 20 | # 21 | # A simple ChContactSurfaceNodeCloud is used to provide collision against 22 | # the floor. 23 | # 24 | # The cable falls under the action of gravity alone, acting in the negative 25 | # Y (up) direction. 26 | # 27 | # The simulation is animated with Irrlicht. 28 | # 29 | # ============================================================================= 30 | 31 | import pychrono as chrono 32 | import pychrono.fea as fea 33 | import pychrono.irrlicht as chronoirr 34 | 35 | # 0. Set the path to the Chrono data folder 36 | CHRONO_DATA_DIR = "E:/Repositories/chrono/data/" 37 | chrono.SetChronoDataPath(CHRONO_DATA_DIR) 38 | 39 | # 1. Create the physical system that will handle all finite elements and constraints. 40 | 41 | # NOTE that we need contact in FEA, so we use the ChSystemSMC, that uses SMC penalty in contacts 42 | system = chrono.ChSystemSMC() 43 | 44 | # 2. Create the mesh that will contain the finite elements, and add it to the system 45 | 46 | mesh = fea.ChMesh() 47 | 48 | system.Add(mesh) 49 | 50 | 51 | ## ------------------------------------------------------------------------- 52 | ## EXERCISE 1 53 | ## 54 | ## Use Euler-Bernoulli beams to make a hanging cable, exactly as in 55 | ## the FEA_cable_collide_1.cpp, but with ChElementBeamEuler elements 56 | ## instead of ChElementCableANCF. 57 | ## The ChElementBeamEuler beams are more sophisticated as they can also 58 | ## simulate torsion and shear, and off-center shear effects. 59 | ## Just use the same for() loops of the previous demo, but use these hints: 60 | ## Hint: when creating the section material, in 3., remember that 61 | ## ChElementBeamEuler needs a ChBeamSectionAdvanced material. 62 | ## Hint: when creating the nodes, in 4., the nodes 63 | ## for ChElementBeamEuler must be of ChNodeFEAxyzrot class 64 | ## i.e. each node has coordinates of type: position, rotation, 65 | ## where X axis of rotated system is the direction of the beam, 66 | ## Y and Z are the section plane. 67 | ## Hint: when creating the elements, in 5., use ChElemetBeamEuler 68 | ## Hint: when creating the truss-node constraint, in 6., use ChLinkMateSpherical 69 | ## 70 | ## ------------------------------------------------------------------------- 71 | 72 | 73 | # 3. Create a material for the beam finite elements. 74 | # TO DO ... 75 | 76 | 77 | 78 | 79 | # 4. Create the nodes 80 | # TO DO .... 81 | 82 | 83 | 84 | 85 | # 5. Create the elements 86 | # TO DO .... 87 | 88 | 89 | 90 | 91 | 92 | # 6. Add constraints 93 | # TO DO .... 94 | 95 | 96 | 97 | 98 | 99 | 100 | # 7. Add a collision mesh to the skin of the finite element mesh 101 | 102 | # - Create a ChContactMaterialSMC , it must be assigned to FEA 103 | # meshes and rigid bodies. The ChSystemSMC requires it! 104 | # - Create a ChContactSurfaceNodeCloud and add to the FEA mesh. 105 | # This is the easiest representation of a FEA contact surface: it 106 | # simply creates contact spheres per each node. So, no edge-edge cases 107 | # can be detected between elements though, but it is enough for 108 | # dense finite elements meshes that collide with large objects. 109 | 110 | # Create a surface material to be shared with some objects 111 | mysurfmaterial = chrono.ChContactMaterialSMC() 112 | mysurfmaterial.SetYoungModulus(6e4) 113 | mysurfmaterial.SetFriction(0.3) 114 | mysurfmaterial.SetRestitution(0.2) 115 | mysurfmaterial.SetAdhesion(0) 116 | 117 | # Create the contact surface and add to the mesh, using our SMC contact material 118 | mcontactcloud = fea.ChContactSurfaceNodeCloud(mysurfmaterial) 119 | mesh.AddContactSurface(mcontactcloud) 120 | 121 | # Must use this to 'populate' the contact surface use larger point size to match beam section radius 122 | mcontactcloud.AddAllNodes(0.01) 123 | 124 | # 8. Create a collision plane, as a huge box 125 | 126 | floor = chrono.ChBodyEasyBox( 127 | 4, 0.2, 4, # x,y,z size 128 | 1000, # density 129 | True, # visible 130 | True, # collide 131 | mysurfmaterial 132 | ) 133 | 134 | system.Add(floor) 135 | 136 | floor.SetFixed(True) 137 | floor.SetPos( chrono.ChVector3d(0,-0.1,0) ) 138 | 139 | # 9. Make the finite elements visible in the 3D view 140 | 141 | # - FEA fisualization can be managed via an easy 142 | # ChVisualizationFEAmesh helper class. 143 | # (Alternatively you could bypass this and output .dat 144 | # files at each step, ex. for VTK or Matalb postprocessing) 145 | # - This will automatically update a triangle mesh (a ChVisualShapeTriangleMesh 146 | # asset that is internally managed) by setting proper 147 | # coordinates and vertex colours as in the FEA elements. 148 | # - Such triangle mesh can be rendered by Irrlicht or POVray or whatever 149 | # postprocessor that can handle a coloured ChVisualShapeTriangleMesh). 150 | # - Do not forget AddAsset() at the end! 151 | 152 | mvisualizebeamA = chrono.ChVisualShapeFEA(mesh) 153 | mvisualizebeamA.SetFEMdataType(chrono.ChVisualShapeFEA.DataType_ANCF_BEAM_AX) 154 | mvisualizebeamA.SetColorscaleMinMax(-0.005, 0.005) 155 | mvisualizebeamA.SetSmoothFaces(True) 156 | mvisualizebeamA.SetWireframe(False) 157 | mesh.AddVisualShapeFEA(mvisualizebeamA) 158 | 159 | mvisualizebeamC = chrono.ChVisualShapeFEA(mesh) 160 | mvisualizebeamC.SetFEMglyphType(chrono.ChVisualShapeFEA.GlyphType_NODE_DOT_POS) 161 | mvisualizebeamC.SetFEMdataType(chrono.ChVisualShapeFEA.DataType_NONE) 162 | mvisualizebeamC.SetSymbolsThickness(0.006) 163 | mvisualizebeamC.SetSymbolsScale(0.005) 164 | mvisualizebeamC.SetZbufferHide(False) 165 | mesh.AddVisualShapeFEA(mvisualizebeamC) 166 | 167 | 168 | # 10. Configure the solver and timestepper 169 | 170 | # - the default SOLVER_SOR of Chrono is not able to manage stiffness matrices 171 | # as required by FEA! we must switch to a different solver. 172 | # - We pick the SOLVER_MINRES solver and we configure it. 173 | # - Note that if you build the MKL module, you could use the more precise MKL solver. 174 | 175 | # Change solver 176 | solver = chrono.ChSolverMINRES() 177 | solver.SetMaxIterations(200) 178 | solver.SetTolerance(1e-10) 179 | solver.EnableWarmStart(True) 180 | system.SetSolver(solver) 181 | 182 | # Change integrator: 183 | # system.SetTimestepperType(ChTimestepper.Type.EULER_IMPLICIT_LINEARIZED) # default: fast, 1st order 184 | # system.SetTimestepperType(ChTimestepper.Type.HHT) # precise, slower, might iterate each step 185 | 186 | 187 | # 11. Prepare visualization with Irrlicht 188 | # Note that Irrlicht uses left-handed frames with Y up. 189 | 190 | # Create the Irrlicht application and set-up the camera. 191 | vis = chronoirr.ChVisualSystemIrrlicht() 192 | vis.SetWindowSize(1024, 768) 193 | vis.SetWindowTitle("FEA cable collide demo") 194 | vis.Initialize() 195 | vis.AddLogo() 196 | vis.AddSkyBox() 197 | vis.AddTypicalLights() 198 | vis.AddCamera(chrono.ChVector3d(0.1, 0.2, -2.0)) 199 | vis.SetSymbolScale(0.1) 200 | vis.AttachSystem(system) 201 | 202 | 203 | # 12. Perform the simulation. 204 | 205 | # Specify the step-size. 206 | step_size = 0.001 207 | realtime_timer = chrono.ChRealtimeStepTimer() 208 | 209 | while vis.Run(): 210 | vis.BeginScene() 211 | 212 | # Render Chrono item assets 213 | vis.Render() 214 | 215 | # Draw an XZ grid at the global origin to add in visualization. 216 | chronoirr.drawGrid( 217 | vis, 0.1, 0.1, 20, 20, 218 | chrono.ChCoordsysd(chrono.ChVector3d(0, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2)), 219 | chrono.ChColor(0.4, 0.7, 0.4), True) 220 | 221 | vis.EndScene() 222 | 223 | ## Advance simulation by one step 224 | system.DoStepDynamics(step_size) 225 | 226 | # Spin in place for real time to catch up 227 | realtime_timer.Spin(step_size) 228 | 229 | -------------------------------------------------------------------------------- /PyChrono/FEA/FEA_cable_collide_1.py: -------------------------------------------------------------------------------- 1 | # ============================================================================= 2 | # PROJECT CHRONO - http:#projectchrono.org 3 | # 4 | # Copyright (c) 2014 projectchrono.org 5 | # All right reserved. 6 | # 7 | # Use of this source code is governed by a BSD-style license that can be found 8 | # in the LICENSE file at the top level of the distribution and at 9 | # http:#projectchrono.org/license-chrono.txt. 10 | # 11 | # ============================================================================= 12 | # Author: Simone Benatti 13 | # ============================================================================= 14 | # 15 | # Create a falling cable using FEA module (FEA tutorial n.1) 16 | # 17 | # This cable is made with N beam elements of ChElementANCFcable type. They are 18 | # added to a ChMesh and then the first node is connected to the absolute 19 | # reference using a constraint. 20 | # 21 | # The cable falls under the action of gravity alone, acting in the negative 22 | # Y (up) direction. 23 | # 24 | # The simulation is animated with Irrlicht. 25 | # 26 | # ============================================================================= 27 | 28 | import pychrono as chrono 29 | import pychrono.fea as fea 30 | import pychrono.irrlicht as chronoirr 31 | 32 | # 0. Set the path to the Chrono data folder 33 | CHRONO_DATA_DIR = "E:/Repositories/chrono/data/" 34 | chrono.SetChronoDataPath(CHRONO_DATA_DIR) 35 | 36 | # 1. Create the physical system that will handle all finite elements and constraints. 37 | 38 | # Specify the gravitational acceleration vector, consistent with the 39 | # global reference frame having Y up (ISO system). 40 | system = chrono.ChSystemNSC() 41 | system.SetGravitationalAcceleration(chrono.ChVector3d(0, -9.81, 0)) 42 | 43 | 44 | # 2. Create the mesh that will contain the finite elements, and add it to the system 45 | 46 | mesh = fea.ChMesh() 47 | 48 | system.Add(mesh) 49 | 50 | 51 | # 3. Create a material for the beam finite elements. 52 | 53 | # Note that each FEA element type requires some corresponding 54 | # type of material. Here we will use ChElementCableANCF elements: 55 | # they use a material of type ChBeamSectionCable, so let's do 56 | 57 | beam_material = fea.ChBeamSectionCable() 58 | beam_material.SetDiameter(0.01) 59 | beam_material.SetYoungModulus(0.01e9) 60 | beam_material.SetBeamRaleyghDamping(0.01) 61 | 62 | 63 | # 4. Create the nodes 64 | 65 | # - We use a simple for() loop to create nodes along the cable. 66 | # - Nodes for ChElementCableANCF must be of ChNodeFEAxyzD class 67 | # i.e. each node has 6 coordinates: position, direction, where 68 | # direction is the tangent to the cable. 69 | # - Each node must be added to the mesh, ex. mesh.Add(my_node) 70 | # - To make things easier in the following, we store node pointers 71 | # into an optional 'beam_nodes' array, i.e. a std::vector<>, later we 72 | # can use such array for easy creation of elements between the nodes. 73 | 74 | beam_nodes = [] 75 | 76 | length = 1.2 # beam length, in meters 77 | N_nodes = 16 78 | for i_ni in range(N_nodes) : 79 | # i-th node position 80 | position = chrono.ChVector3d(length * (i_ni / (N_nodes - 1)), # node position, x 81 | 0.5, # node position, y 82 | 0) # node position, z 83 | 84 | # i-th node direction 85 | direction = chrono.ChVector3d(1.0, 0, 0) 86 | 87 | # create the node 88 | node = fea.ChNodeFEAxyzD(position, direction) 89 | 90 | # add it to mesh 91 | mesh.AddNode(node) 92 | 93 | # add it to the auxiliary beam_nodes 94 | beam_nodes.append(node) 95 | 96 | 97 | 98 | # 5. Create the elements 99 | 100 | # - We use a simple for() loop to create elements between the 101 | # nodes that we already created. 102 | # - Each element must be set with the ChBeamSectionCable material 103 | # that we already created 104 | # - Each element must be added to the mesh, ex. mesh.Add(my_element) 105 | 106 | for ie in range(N_nodes - 1) : 107 | # create the element 108 | element = fea.ChElementCableANCF() 109 | 110 | # set the connected nodes (pick two consecutive nodes in our beam_nodes container) 111 | element.SetNodes(beam_nodes[ie], beam_nodes[ie + 1]) 112 | 113 | # set the material 114 | element.SetSection(beam_material) 115 | 116 | # add it to mesh 117 | mesh.AddElement(element) 118 | 119 | 120 | 121 | # 6. Add constraints 122 | 123 | # - Constraints can be applied to FEA nodes 124 | # - For the ChNodeFEAxyzD there are specific constraints that 125 | # can be used to connect them to a ChBody, namely 126 | # ChLinkNodeFrame and ChLinkNodeSlopeFrame 127 | # - To attach one end of the beam to the ground, we need a 128 | # 'truss' ChBody that is fixed. 129 | # - Note. An alternative, only when the node must be fixed 130 | # to absolute reference, is not using constraints, and just 131 | # use: beam_nodes[0].SetFixed(True) (but would fix also dir) 132 | 133 | truss = chrono.ChBody() 134 | truss.SetFixed(True) 135 | system.Add(truss) 136 | 137 | # lock an end of the wire to the truss 138 | constraint_pos = fea.ChLinkNodeFrame() 139 | constraint_pos.Initialize(beam_nodes[0], truss) 140 | system.Add(constraint_pos) 141 | 142 | 143 | ## ------------------------------------------------------------------------- 144 | ## EXERCISE 1a 145 | ## 146 | ## Add a cylinder. 147 | ## Suggested size: 0.02 radius, 0.1 height, density:1000. 148 | ## Hint: use the ChBodyEasyCylinder to make the cylinder, pass size as 149 | ## parameters in construction. 150 | ## 151 | ## ------------------------------------------------------------------------- 152 | 153 | 154 | # TO DO ... 155 | 156 | 157 | ## ------------------------------------------------------------------------- 158 | ## EXERCISE 1b 159 | ## 160 | ## Attach the cylinder to the free end of the cable. 161 | ## Hint: use the ChLinkNodeFrame to connect the cylinder and the end node. 162 | ## 163 | ## ------------------------------------------------------------------------- 164 | 165 | # TO DO ... 166 | 167 | 168 | # 7. Make the finite elements visible in the 3D view 169 | 170 | # - FEA fisualization can be managed via an easy 171 | # ChVisualShapeFEA helper class. 172 | # (Alternatively you could bypass this and output .dat 173 | # files at each step, ex. for VTK or Matalb postprocessing) 174 | # - This will automatically update a triangle mesh (a ChVisualShapeTriangleMesh 175 | # asset that is internally managed) by setting proper 176 | # coordinates and vertex colours as in the FEA elements. 177 | # - Such triangle mesh can be rendered by Irrlicht or POVray or whatever 178 | # postprocessor that can handle a coloured ChVisualShapeTriangleMesh). 179 | 180 | mvisualizebeamA = chrono.ChVisualShapeFEA(mesh) 181 | mvisualizebeamA.SetFEMdataType(chrono.ChVisualShapeFEA.DataType_ANCF_BEAM_AX) 182 | mvisualizebeamA.SetColorscaleMinMax(-0.005, 0.005) 183 | mvisualizebeamA.SetSmoothFaces(True) 184 | mvisualizebeamA.SetWireframe(False) 185 | mesh.AddVisualShapeFEA(mvisualizebeamA) 186 | 187 | mvisualizebeamC = chrono.ChVisualShapeFEA(mesh) 188 | mvisualizebeamC.SetFEMglyphType(chrono.ChVisualShapeFEA.GlyphType_NODE_DOT_POS) 189 | mvisualizebeamC.SetFEMdataType(chrono.ChVisualShapeFEA.DataType_NONE) 190 | mvisualizebeamC.SetSymbolsThickness(0.006) 191 | mvisualizebeamC.SetSymbolsScale(0.005) 192 | mvisualizebeamC.SetZbufferHide(False) 193 | mesh.AddVisualShapeFEA(mvisualizebeamC) 194 | 195 | 196 | # 8. Configure the solver and timestepper 197 | 198 | # - the default SOLVER_SOR of Chrono is not able to manage stiffness matrices 199 | # as required by FEA! we must switch to a different solver. 200 | # - We pick the SOLVER_MINRES solver and we configure it. 201 | # - Note that if you build the MKL module, you could use the more precise MKL solver. 202 | 203 | solver = chrono.ChSolverMINRES() 204 | solver.SetMaxIterations(200) 205 | solver.SetTolerance(1e-10) 206 | solver.EnableWarmStart(True) 207 | system.SetSolver(solver) 208 | 209 | # Change integrator: 210 | system.SetTimestepperType(chrono.ChTimestepper.Type_EULER_IMPLICIT_LINEARIZED) # default: fast, 1st order 211 | # system.SetTimestepperType(ChTimestepper::Type::HHT) # precise, slower, might iterate each step 212 | 213 | 214 | # 9. Prepare visualization with Irrlicht 215 | # Note that Irrlicht uses left-handed frames with Y up. 216 | 217 | # Create the Irrlicht application and set-up the camera. 218 | vis = chronoirr.ChVisualSystemIrrlicht() 219 | vis.SetWindowSize(1024, 768) 220 | vis.SetWindowTitle("FEA cable collide demo") 221 | vis.Initialize() 222 | vis.AddLogo() 223 | vis.AddSkyBox() 224 | vis.AddTypicalLights() 225 | vis.AddCamera(chrono.ChVector3d(0.1, 0.2, -2.0)) 226 | vis.SetSymbolScale(0.1) 227 | vis.AttachSystem(system) 228 | 229 | 230 | # 10. Perform the simulation. 231 | 232 | # Specify the step-size. 233 | step_size = 0.001 234 | realtime_timer = chrono.ChRealtimeStepTimer() 235 | 236 | while vis.Run(): 237 | vis.BeginScene() 238 | 239 | # Render Chrono item assets 240 | vis.Render() 241 | 242 | # Draw an XZ grid at the global origin to add in visualization. 243 | chronoirr.drawGrid( 244 | vis, 0.1, 0.1, 20, 20, 245 | chrono.ChCoordsysd(chrono.ChVector3d(0, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2)), 246 | chrono.ChColor(0.4, 0.7, 0.4), True) 247 | 248 | vis.EndScene() 249 | 250 | ## Advance simulation by one step 251 | system.DoStepDynamics(step_size) 252 | 253 | # Spin in place for real time to catch up 254 | realtime_timer.Spin(step_size) 255 | 256 | -------------------------------------------------------------------------------- /PyChrono/slider-crank/slider_crank_1_solution.py: -------------------------------------------------------------------------------- 1 | ## ============================================================================= 2 | ## PROJECT CHRONO - http:##projectchrono.org 3 | ## 4 | ## Copyright (c) 2014 projectchrono.org 5 | ## All right reserved. 6 | ## 7 | ## Use of this source code is governed by a BSD-style license that can be found 8 | ## in the LICENSE file at the top level of the distribution and at 9 | ## http://projectchrono.org/license-chrono.txt. 10 | ## 11 | ## ============================================================================= 12 | ## Author: Simone Benatti 13 | ## ============================================================================= 14 | ## 15 | ## Slider-crank Chrono tutorial (model 1) 16 | ## 17 | ## This model is a 3-body slider-crank consisting of crank, slider and connecting 18 | ## rod bodies. The crank is connected to ground with a revolute joint and the 19 | ## slider is connected to ground through a prismatic joint. The connecting rod 20 | ## connects to the crank through a spherical joint and to the slider through a 21 | ## universal joint. 22 | ## 23 | ## The crank body is driven at constant angular speed, under the action of gravity, 24 | ## acting in the negative Z direction. 25 | ## 26 | ## The simulation is animated with Irrlicht. 27 | ## 28 | ## ============================================================================= 29 | 30 | import pychrono as chrono 31 | from pychrono import irrlicht as chronoirr 32 | 33 | ## 0. Set the path to the Chrono data folder 34 | chrono.SetChronoDataPath('E:/Repositories/chrono/data/') 35 | 36 | ## 1. Create the physical system that will handle all bodies and constraints. 37 | 38 | ## Specify the gravitational acceleration vector, consistent with the 39 | ## global reference frame having Z up. 40 | system = chrono.ChSystemNSC() 41 | system.SetGravitationalAcceleration(chrono.ChVector3d(0, 0, -9.81)) 42 | 43 | ## 2. Create the rigid bodies of the slider-crank mechanical system. 44 | ## For each body, specify: 45 | ## - a unique identifier 46 | ## - mass and moments of inertia 47 | ## - position and orientation of the (centroidal) body frame 48 | ## - visualization assets (defined with respect to the body frame) 49 | 50 | ## Ground 51 | ground = chrono.ChBody() 52 | system.AddBody(ground) 53 | ground.SetIdentifier(-1) 54 | ground.SetName("ground") 55 | ground.SetFixed(True) 56 | 57 | cyl_g = chrono.ChVisualShapeCylinder(0.03, 0.4) 58 | cyl_g.SetColor(chrono.ChColor(0.6, 0.6, 0.2)) 59 | ground.AddVisualShape(cyl_g) 60 | 61 | ## Crank 62 | crank = chrono.ChBody() 63 | system.AddBody(crank) 64 | crank.SetIdentifier(1) 65 | crank.SetName("crank") 66 | crank.SetMass(1.0) 67 | crank.SetInertiaXX(chrono.ChVector3d(0.005, 0.1, 0.1)) 68 | crank.SetPos(chrono.ChVector3d(-1, 0, 0)) 69 | crank.SetRot(chrono.ChQuaterniond(1, 0, 0, 0)) 70 | 71 | box_c = chrono.ChVisualShapeBox(1.9, 0.1, 0.1) 72 | crank.AddVisualShape(box_c) 73 | 74 | cyl_c = chrono.ChVisualShapeCylinder(0.05, 0.2) 75 | crank.AddVisualShape(cyl_c, chrono.ChFramed(chrono.ChVector3d(1, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2))) 76 | 77 | sph_c = chrono.ChVisualShapeSphere(0.05) 78 | sph_c.SetColor(chrono.ChColor(0.6, 0.2, 0.2)) 79 | crank.AddVisualShape(sph_c, chrono.ChFramed(chrono.ChVector3d(-1, 0, 0))) 80 | 81 | ## Slider 82 | slider = chrono.ChBody() 83 | system.AddBody(slider) 84 | slider.SetIdentifier(2) 85 | slider.SetName("slider") 86 | slider.SetMass(1.0) 87 | slider.SetInertiaXX(chrono.ChVector3d(0.05, 0.05, 0.05)) 88 | slider.SetPos(chrono.ChVector3d(2, 0, 0)) 89 | slider.SetRot(chrono.ChQuaterniond(1, 0, 0, 0)) 90 | 91 | box_s = chrono.ChVisualShapeBox(0.4, 0.2, 0.2) 92 | box_s.SetColor(chrono.ChColor(0.2, 0.2, 0.6)) 93 | slider.AddVisualShape(box_s) 94 | 95 | #### ------------------------------------------------------------------------- 96 | #### EXERCISE 1.1 97 | #### Create a connecting rod body to replace the distance constraint. 98 | #### This body should have: 99 | #### mass: 0.5 100 | #### moments of inertia: I_xx = 0.005, I_yy = 0.1, I_zz = 0.1 101 | #### visualization: a green box with width and height 0.1 102 | #### ------------------------------------------------------------------------- 103 | 104 | ## Connecting rod 105 | rod = chrono.ChBody() 106 | system.AddBody(rod) 107 | rod.SetIdentifier(3) 108 | rod.SetName("rod") 109 | rod.SetMass(0.5) 110 | rod.SetMass(0.5) 111 | rod.SetInertiaXX(chrono.ChVector3d(0.005, 0.1, 0.1)) 112 | rod.SetPos(chrono.ChVector3d(0, 0, 0)) 113 | rod.SetRot(chrono.ChQuaterniond(1, 0, 0, 0)) 114 | 115 | box_r = chrono.ChVisualShapeBox(4, 0.1, 0.1) 116 | rod.AddVisualShape(box_r) 117 | 118 | cyl_r = chrono.ChVisualShapeCylinder(0.03, 0.4) 119 | cyl_r.SetColor(chrono.ChColor(0.2, 0.6, 0.2)) 120 | rod.AddVisualShape(cyl_r, chrono.ChFramed(chrono.ChVector3d(2, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2))); 121 | 122 | ## 3. Create joint constraints. 123 | ## All joint frames are specified in the global frame. 124 | 125 | ## Define two quaternions representing: 126 | ## - a rotation of -90 degrees around x (z2y) 127 | ## - a rotation of +90 degrees around y (z2x) 128 | z2y = chrono.ChQuaterniond() 129 | z2x = chrono.ChQuaterniond() 130 | z2y.SetFromAngleX(-chrono.CH_PI / 2) 131 | z2x.SetFromAngleY(chrono.CH_PI / 2) 132 | 133 | #### ------------------------------------------------------------------------- 134 | #### EXERCISE 1.2 135 | #### Replace the revolute joint between ground and crank with a 136 | #### ChLinkMotorRotationSpeed element and enforce constant angular speed of 137 | #### 90 degrees/s. 138 | #### ------------------------------------------------------------------------- 139 | 140 | # Create a ChFunction object that always returns the constant value PI/2. 141 | fun = chrono.ChFunctionConst() 142 | fun.Set_yconst(chrono.CH_PI) 143 | 144 | # Motor between ground and crank. 145 | # Note that this also acts as a revolute joint (i.e. it enforces the same 146 | # kinematic constraints as a revolute joint). As before, we apply the 'z2y' 147 | # rotation to align the rotation axis with the Y axis of the global frame. 148 | engine_ground_crank = chrono.ChLinkMotorRotationSpeed() 149 | engine_ground_crank.SetName("engine_ground_crank") 150 | engine_ground_crank.Initialize(ground, crank, chrono.ChFramed(chrono.ChVector3d(0, 0, 0), z2y)) 151 | engine_ground_crank.SetSpeedFunction(fun) 152 | system.AddLink(engine_ground_crank) 153 | 154 | ## Prismatic joint between ground and slider. 155 | ## The translational axis of a prismatic joint is along the Z axis of the 156 | ## specified joint coordinate system. Here, we apply the 'z2x' rotation to 157 | ## align it with the X axis of the global reference frame. 158 | prismatic_ground_slider = chrono.ChLinkLockPrismatic() 159 | prismatic_ground_slider.SetName("prismatic_ground_slider") 160 | prismatic_ground_slider.Initialize(ground, slider, chrono.ChFramed(chrono.ChVector3d(2, 0, 0), z2x)) 161 | system.AddLink(prismatic_ground_slider) 162 | 163 | #### ------------------------------------------------------------------------- 164 | #### EXERCISE 1.3 165 | #### Replace the distance constraint with joints connecting the rod to the 166 | #### crank (use ChLinkLockSpherical) and to the slider (ChLinkUniversal). The 167 | #### universal joint's cross should be aligned with the Z and Y global axes. 168 | #### ------------------------------------------------------------------------- 169 | 170 | # Spherical joint between crank and rod 171 | spherical_crank_rod = chrono.ChLinkLockSpherical() 172 | spherical_crank_rod.SetName("spherical_crank_rod") 173 | spherical_crank_rod.Initialize(crank, rod, chrono.ChFramed(chrono.ChVector3d(-2, 0, 0), chrono.QUNIT)) 174 | system.AddLink(spherical_crank_rod) 175 | 176 | # Universal joint between rod and slider. 177 | # The "cross" of a universal joint is defined using the X and Y axes of the 178 | # specified joint coordinate frame. Here, we apply the 'z2x' rotation so that 179 | # the cross is aligned with the Z and Y axes of the global reference frame. 180 | universal_rod_slider = chrono.ChLinkUniversal() 181 | universal_rod_slider.SetName("universal_rod_slider") 182 | universal_rod_slider.Initialize(rod, slider, chrono.ChFramed(chrono.ChVector3d(2, 0, 0), z2x)) 183 | system.AddLink(universal_rod_slider) 184 | 185 | ## 4. Write the system hierarchy to the console (default log output destination) 186 | ####system.ShowHierarchy(chrono.GetLog()) 187 | 188 | ## 5. Prepare visualization with Irrlicht 189 | ## Note that Irrlicht uses left-handed frames with Y up. 190 | 191 | ## Create the Irrlicht application and set-up the camera. 192 | vis = chronoirr.ChVisualSystemIrrlicht() 193 | vis.AttachSystem(system) 194 | vis.SetWindowSize(1024,768) 195 | vis.SetWindowTitle('Slider-Crank Demo 1') 196 | vis.SetCameraVertical(chrono.CameraVerticalDir_Z) 197 | vis.Initialize() 198 | vis.AddLogo(chrono.GetChronoDataFile('logo_pychrono_alpha.png')) 199 | vis.AddSkyBox() 200 | vis.AddCamera(chrono.ChVector3d(2, -5, 0), chrono.ChVector3d(2, 0, 0)) 201 | vis.AddTypicalLights() 202 | 203 | ## 6. Perform the simulation. 204 | 205 | ## Specify the step-size. 206 | step_size = 0.01 207 | realtime_timer = chrono.ChRealtimeStepTimer() 208 | 209 | while (vis.Run()): 210 | vis.BeginScene() 211 | 212 | # Render Chrono item assets 213 | vis.Render() 214 | 215 | ## Draw an XZ grid at the global origin to add in visualization 216 | chronoirr.drawGrid( 217 | vis, 1, 1, 20, 20, 218 | chrono.ChCoordsysd(chrono.ChVector3d(0, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2)), 219 | chrono.ChColor(0.4, 0.7, 0.4), True) 220 | chronoirr.drawAllCOGs(vis, 1) 221 | 222 | vis.EndScene() 223 | 224 | ## Advance simulation by one step 225 | system.DoStepDynamics(step_size) 226 | 227 | # Spin in place for real time to catch up 228 | realtime_timer.Spin(step_size) 229 | -------------------------------------------------------------------------------- /Chrono/multicore/cratering.cpp: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // PROJECT CHRONO - http://projectchrono.org 3 | // 4 | // Copyright (c) 2014 projectchrono.org 5 | // All right reserved. 6 | // 7 | // Use of this source code is governed by a BSD-style license that can be found 8 | // in the LICENSE file at the top level of the distribution and at 9 | // http://projectchrono.org/license-chrono.txt. 10 | // 11 | // ============================================================================= 12 | // Author: Radu Serban 13 | // ============================================================================= 14 | // 15 | // Chrono::Multicore tutorial. 16 | // 17 | // The model simulated here consists of a spherical projectile dropped in a 18 | // bed of granular material, using either penalty or complementarity method for 19 | // frictional contact. 20 | // 21 | // The global reference frame has Z up. 22 | // All units SI. 23 | // ============================================================================= 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "chrono/ChConfig.h" 30 | #include "chrono/utils/ChUtilsCreators.h" 31 | #include "chrono/utils/ChUtilsGenerators.h" 32 | 33 | #include "chrono_multicore/physics/ChSystemMulticore.h" 34 | 35 | #ifdef CHRONO_VSG 36 | #include "chrono_vsg/ChVisualSystemVSG.h" 37 | using namespace chrono::vsg3d; 38 | #endif 39 | 40 | using namespace chrono; 41 | 42 | using std::cout; 43 | using std::endl; 44 | using std::flush; 45 | 46 | // ----------------------------------------------------------------------------- 47 | // Problem definitions 48 | // ----------------------------------------------------------------------------- 49 | 50 | // Desired number of OpenMP threads (will be clamped to maximum available) 51 | int threads = 4; 52 | 53 | // Parameters for the granular material 54 | int tag_particles = 0; // all particles wilkl have tag at least this value 55 | double r_g = 2e-3; 56 | double rho_g = 2500; 57 | double vol_g = (4.0 / 3) * CH_PI * r_g * r_g * r_g; 58 | double mass_g = rho_g * vol_g; 59 | ChVector3d inertia_g = 0.4 * mass_g * r_g * r_g * ChVector3d(1, 1, 1); 60 | 61 | float Y_g = 1e7f; 62 | float mu_g = 0.3f; 63 | float cr_g = 0.1f; 64 | 65 | // Parameters for the falling ball 66 | double R_b = 1.5e-2; 67 | double rho_b = 700; 68 | double vol_b = (4.0 / 3) * CH_PI * R_b * R_b * R_b; 69 | double mass_b = rho_b * vol_b; 70 | ChVector3d inertia_b = 0.4 * mass_b * R_b * R_b * ChVector3d(1, 1, 1); 71 | 72 | float Y_b = 1e8f; 73 | float mu_b = 0.3f; 74 | float cr_b = 0.1f; 75 | 76 | // Parameters for the containing bin 77 | double hDimX = 4e-2; // length in x direction 78 | double hDimY = 4e-2; // depth in y direction 79 | double hDimZ = 4e-2; // height in z direction 80 | double hThickness = 0.5e-2; // wall thickness 81 | 82 | float Y_c = 2e6f; 83 | float mu_c = 0.3f; 84 | float cr_c = 0.1f; 85 | 86 | // Drop height and vertical velocity 87 | double initial_height = 0.1; 88 | double initial_velocity = 0; 89 | 90 | // ----------------------------------------------------------------------------- 91 | // Create the container (five boxes) 92 | // ----------------------------------------------------------------------------- 93 | void CreateContainer(ChSystemMulticore* system) { 94 | // Create a material for the container 95 | auto material_c = chrono_types::make_shared(); 96 | material_c->SetFriction(mu_c); 97 | 98 | // Create the container. This utility function creates the container body (fixed to "ground") 99 | // and sets both the contact and visualization shapes. 100 | utils::CreateBoxContainer(system, material_c, ChVector3d(hDimX, hDimY, hDimZ), hThickness); 101 | } 102 | 103 | // ----------------------------------------------------------------------------- 104 | // Create the falling ball at the specified height, with specified vertical 105 | // initial velocity. 106 | // ----------------------------------------------------------------------------- 107 | std::shared_ptr CreateFallingBall(ChSystemMulticore* system) { 108 | // Create a contact material for the falling ball 109 | auto material_b = chrono_types::make_shared(); 110 | material_b->SetFriction(mu_b); 111 | 112 | // Create the falling ball body 113 | auto ball = chrono_types::make_shared(); 114 | 115 | ball->SetMass(mass_b); 116 | ball->SetInertiaXX(inertia_b); 117 | ball->SetPos(ChVector3d(0, 0, initial_height)); 118 | ball->SetRot(ChQuaternion<>(1, 0, 0, 0)); 119 | ball->SetLinVel(ChVector3d(0, 0, initial_velocity)); 120 | ball->EnableCollision(true); 121 | ball->SetFixed(false); 122 | 123 | // Specify spherical contact and visualization shapes 124 | utils::AddSphereGeometry(ball.get(), material_b, R_b); 125 | 126 | system->AddBody(ball); 127 | 128 | return ball; 129 | } 130 | 131 | // ----------------------------------------------------------------------------- 132 | // Create the granular material, consisting of identical spheres with given 133 | // radius and material properties; the spheres are generated in a prismatic 134 | // region inside the container, using Poisson Disk sampling (thus ensuring that 135 | // no two spheres are closer than twice the radius) 136 | // ----------------------------------------------------------------------------- 137 | void CreateObjects(ChSystemMulticore* system) { 138 | // Create a contact material for granular bodies 139 | auto material_g = chrono_types::make_shared(); 140 | material_g->SetFriction(mu_g); 141 | 142 | //// ******************************************************************************** 143 | //// EXERCISE: 144 | //// Create a granular material generator with a mixture entirely made out of spheres 145 | //// of equal radius, all sharing the same contact material 146 | //// ******************************************************************************** 147 | } 148 | 149 | // ----------------------------------------------------------------------------- 150 | int main(int argc, char* argv[]) { 151 | // Set the path to the Chrono data folder. 152 | SetChronoDataPath(CHRONO_DATA_DIR); 153 | 154 | // Create the (multicore) system and set method-specific solver settings. 155 | ChSystemMulticore* system = new ChSystemMulticoreNSC; 156 | 157 | system->SetCollisionSystemType(ChCollisionSystem::Type::MULTICORE); 158 | 159 | system->GetSettings()->solver.solver_type = SolverType::BB; 160 | system->GetSettings()->solver.solver_mode = SolverMode::SLIDING; 161 | system->GetSettings()->solver.max_iteration_normal = 0; 162 | system->GetSettings()->solver.max_iteration_sliding = 100; 163 | system->GetSettings()->solver.max_iteration_spinning = 0; 164 | system->GetSettings()->solver.alpha = 0; 165 | system->GetSettings()->solver.contact_recovery_speed = 0.1; 166 | 167 | double time_step = 1e-3; 168 | 169 | // Set number of threads. 170 | int max_threads = omp_get_num_procs(); 171 | if (threads > max_threads) 172 | threads = max_threads; 173 | omp_set_num_threads(threads); 174 | std::cout << "Using " << threads << " threads" << std::endl; 175 | 176 | // Set gravitational acceleration 177 | system->SetGravitationalAcceleration(ChVector3d(0, 0, -9.81)); 178 | 179 | // Set method-independent solver settings 180 | system->GetSettings()->solver.use_full_inertia_tensor = false; 181 | system->GetSettings()->solver.tolerance = 1.0; 182 | 183 | system->GetSettings()->collision.narrowphase_algorithm = ChNarrowphase::Algorithm::HYBRID; 184 | system->GetSettings()->collision.collision_envelope = 0.05 * r_g; 185 | 186 | //// ****************************************************** 187 | //// EXERCISE: 188 | //// Provide a more efficient split of bins for broad-phase 189 | //// ****************************************************** 190 | system->GetSettings()->collision.bins_per_axis = vec3(1, 1, 1); 191 | 192 | // Create the objects 193 | CreateContainer(system); 194 | auto ball = CreateFallingBall(system); 195 | CreateObjects(system); 196 | 197 | // Simulation loop 198 | 199 | #ifdef CHRONO_VSG 200 | auto vis = chrono_types::make_shared(); 201 | vis->AttachSystem(system); 202 | vis->SetWindowTitle("Crater Test"); 203 | vis->SetWindowSize(1280, 720); 204 | vis->SetCameraVertical(CameraVerticalDir::Z); 205 | vis->AddCamera(ChVector3d(0, -7 * hDimY, hDimZ), ChVector3d(0, 0, hDimZ)); 206 | vis->SetCameraAngleDeg(40.0); 207 | vis->SetBackgroundColor(ChColor(0.8f, 0.85f, 0.9f)); 208 | vis->EnableSkyBox(); 209 | vis->SetLightIntensity(1.0f); 210 | vis->SetLightDirection(1.5 * CH_PI_2, CH_PI_4); 211 | vis->EnableShadows(); 212 | vis->Initialize(); 213 | #endif 214 | 215 | double out_fps = 120; 216 | 217 | double time_end = 5; 218 | double time = 0; 219 | int sim_frame = 0; 220 | int out_frame = 0; 221 | double exec_time = 0; 222 | int num_contacts = 0; 223 | 224 | while (time < time_end) { 225 | if (time >= out_frame / out_fps) { 226 | cout << endl; 227 | cout << "---- Frame: " << out_frame << endl; 228 | cout << " Sim frame: " << sim_frame << endl; 229 | cout << " Time: " << time << endl; 230 | cout << " Num. contacts: " << num_contacts << endl; 231 | 232 | out_frame++; 233 | num_contacts = 0; 234 | } 235 | 236 | // Advance simulation by one step 237 | #ifdef CHRONO_VSG 238 | if (vis->Run()) { 239 | system->DoStepDynamics(time_step); 240 | vis->Render(); 241 | } else 242 | break; 243 | #else 244 | system->DoStepDynamics(time_step); 245 | #endif 246 | 247 | time += time_step; 248 | sim_frame++; 249 | num_contacts += system->GetNumContacts(); 250 | } 251 | 252 | delete system; 253 | return 0; 254 | } 255 | -------------------------------------------------------------------------------- /Chrono/wheeled_vehicle/wheeled_vehicle.cpp: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // PROJECT CHRONO - http://projectchrono.org 3 | // 4 | // Copyright (c) 2014 projectchrono.org 5 | // All right reserved. 6 | // 7 | // Use of this source code is governed by a BSD-style license that can be found 8 | // in the LICENSE file at the top level of the distribution and at 9 | // http://projectchrono.org/license-chrono.txt. 10 | // 11 | // ============================================================================= 12 | // Authors: Radu Serban 13 | // ============================================================================= 14 | // 15 | // Main driver function for a wheeled vehicle specified through JSON files. 16 | // 17 | // The vehicle reference frame has Z up, X towards the front of the vehicle, and 18 | // Y pointing to the left. 19 | // 20 | // ============================================================================= 21 | 22 | #include "chrono/ChConfig.h" 23 | #include "chrono/core/ChRealtimeStep.h" 24 | #include "chrono/core/ChRandom.h" 25 | #include "chrono/physics/ChSystemSMC.h" 26 | #include "chrono/physics/ChSystem.h" 27 | #include "chrono/physics/ChBodyEasy.h" 28 | #include "chrono/core/ChRandom.h" 29 | 30 | #include "chrono_vehicle/ChVehicleDataPath.h" 31 | #include "chrono_vehicle/utils/ChUtilsJSON.h" 32 | 33 | #include "chrono_vehicle/powertrain/EngineSimple.h" 34 | #include "chrono_vehicle/powertrain/AutomaticTransmissionSimpleMap.h" 35 | #include "chrono_vehicle/terrain/RigidTerrain.h" 36 | #include "chrono_vehicle/driver/ChInteractiveDriver.h" 37 | 38 | #include "chrono_vehicle/wheeled_vehicle/vehicle/WheeledVehicle.h" 39 | #include "chrono_vehicle/wheeled_vehicle/tire/RigidTire.h" 40 | #include "chrono_vehicle/wheeled_vehicle/ChWheeledVehicleVisualSystemIrrlicht.h" 41 | 42 | using namespace chrono; 43 | using namespace chrono::vehicle; 44 | 45 | // ============================================================================= 46 | 47 | std::string vehicle_file("vehicle/WheeledVehicle.json"); 48 | std::string tire_file("vehicle/RigidTire.json"); 49 | std::string engine_file("vehicle/EngineSimple.json"); 50 | std::string transmission_file("vehicle/AutomaticTransmissionSimpleMap.json"); 51 | 52 | std::string rigidterrain_file("terrain/RigidPlane.json"); 53 | 54 | // Initial vehicle position and orientation 55 | ChVector3d initLoc(0, 0, 1.0); 56 | ChQuaternion<> initRot(1, 0, 0, 0); 57 | 58 | // Simulation step size 59 | double step_size = 2e-3; 60 | 61 | // Time interval between two render frames 62 | double render_step_size = 1.0 / 50; // FPS = 50 63 | 64 | // Point on chassis tracked by the camera 65 | ChVector3d trackPoint(0.0, 0.0, 1.75); 66 | 67 | // Contact method 68 | auto NSC_SMC = ChContactMethod::NSC; 69 | 70 | // ============================================================================= 71 | 72 | void AddMovingObstacles(ChSystem* system); 73 | void AddFixedObstacles(ChSystem* system); 74 | 75 | // ============================================================================= 76 | 77 | int main(int argc, char* argv[]) { 78 | // ---------------------- 79 | // Set path to data files 80 | // ---------------------- 81 | 82 | // Path to Chrono data files (textures, etc.) 83 | SetChronoDataPath(CHRONO_DATA_DIR); 84 | 85 | // Path to the data files for this vehicle (JSON specification files) 86 | SetVehicleDataPath(std::string(SOURCE_DIR) + "/data/"); 87 | 88 | // -------------------------- 89 | // Create the various modules 90 | // -------------------------- 91 | 92 | // Create and initialize the vehicle system 93 | WheeledVehicle vehicle(GetVehicleDataFile(vehicle_file), NSC_SMC); 94 | 95 | vehicle.Initialize(ChCoordsys<>(initLoc, initRot)); 96 | 97 | vehicle.SetSuspensionVisualizationType(VisualizationType::PRIMITIVES); 98 | vehicle.SetSteeringVisualizationType(VisualizationType::PRIMITIVES); 99 | vehicle.SetWheelVisualizationType(VisualizationType::NONE); 100 | 101 | // Create the terrain 102 | RigidTerrain terrain(vehicle.GetSystem(), GetVehicleDataFile(rigidterrain_file)); 103 | terrain.Initialize(); 104 | AddFixedObstacles(vehicle.GetSystem()); 105 | AddMovingObstacles(vehicle.GetSystem()); 106 | 107 | // Create and initialize the powertrain system 108 | auto engine = ReadEngineJSON(GetVehicleDataFile(engine_file)); 109 | auto transmission = ReadTransmissionJSON(GetVehicleDataFile(transmission_file)); 110 | auto powertrain = chrono_types::make_shared(engine, transmission); 111 | vehicle.InitializePowertrain(powertrain); 112 | 113 | // Create and initialize the tires 114 | for (auto& axle : vehicle.GetAxles()) { 115 | auto tireL = ReadTireJSON(GetVehicleDataFile(tire_file)); 116 | auto tireR = ReadTireJSON(GetVehicleDataFile(tire_file)); 117 | vehicle.InitializeTire(tireL, axle->m_wheels[0]); 118 | vehicle.InitializeTire(tireR, axle->m_wheels[1]); 119 | } 120 | 121 | // Set collision detection system 122 | vehicle.GetSystem()->SetCollisionSystemType(ChCollisionSystem::Type::BULLET); 123 | 124 | // Create the driver system (interactive) 125 | ChInteractiveDriver driver(vehicle); 126 | driver.SetSteeringDelta(0.02); 127 | driver.SetThrottleDelta(0.02); 128 | driver.SetBrakingDelta(0.06); 129 | driver.Initialize(); 130 | 131 | // Create the Irrlicht vehicle application 132 | auto vis = chrono_types::make_shared(); 133 | vis->SetWindowTitle("Vehicle Demo"); 134 | vis->SetChaseCamera(trackPoint, 5.0, 0.5); 135 | vis->Initialize(); 136 | vis->AddTypicalLights(); 137 | vis->AddSkyBox(); 138 | vis->AddLogo(); 139 | vis->AttachVehicle(&vehicle); 140 | vis->AttachDriver(&driver); 141 | 142 | // --------------- 143 | // Simulation loop 144 | // --------------- 145 | 146 | // Initialize simulation frame counter and simulation time 147 | double time = 0; 148 | 149 | vehicle.EnableRealtime(true); 150 | 151 | while (vis->Run()) { 152 | // Render scene 153 | vis->BeginScene(); 154 | vis->Render(); 155 | vis->EndScene(); 156 | 157 | // Get driver inputs 158 | DriverInputs driver_inputs = driver.GetInputs(); 159 | 160 | // Update modules (process inputs from other modules) 161 | time = vehicle.GetSystem()->GetChTime(); 162 | driver.Synchronize(time); 163 | vehicle.Synchronize(time, driver_inputs, terrain); 164 | terrain.Synchronize(time); 165 | vis->Synchronize(time, driver_inputs); 166 | 167 | // Advance simulation for one timestep for all modules 168 | driver.Advance(step_size); 169 | vehicle.Advance(step_size); 170 | terrain.Advance(step_size); 171 | vis->Advance(step_size); 172 | } 173 | 174 | return 0; 175 | } 176 | 177 | void AddMovingObstacles(ChSystem* system) { 178 | // Create contact material, of appropriate type. Use default properties 179 | std::shared_ptr material; 180 | switch (NSC_SMC) { 181 | case ChContactMethod::NSC: { 182 | auto matNSC = chrono_types::make_shared(); 183 | // Change NSC material properties as desired 184 | material = matNSC; 185 | break; 186 | } 187 | case ChContactMethod::SMC: { 188 | auto matSMC = chrono_types::make_shared(); 189 | // Change SMC material properties as desired 190 | material = matSMC; 191 | break; 192 | } 193 | } 194 | 195 | double sizeX = 300; 196 | double sizeY = 300; 197 | double height = 0; 198 | int numObstacles = 10; 199 | 200 | for (int i = 0; i < numObstacles; i++) { 201 | double o_sizeX = 1.0 + 6.0 * ChRandom::Get(); 202 | double o_sizeY = 0.3 + 0.4 * ChRandom::Get(); 203 | double o_sizeZ = 0.05 + 0.2 * ChRandom::Get(); 204 | auto obstacle = chrono_types::make_shared(o_sizeX, o_sizeY, o_sizeZ, 2000.0, true, true, material); 205 | 206 | double o_posX = (ChRandom::Get() - 0.5) * 0.4 * sizeX; 207 | double o_posY = (ChRandom::Get() - 0.5) * 0.4 * sizeY; 208 | double o_posZ = height + 4; 209 | ChQuaternion<> rot(ChRandom::Get(), ChRandom::Get(), ChRandom::Get(), ChRandom::Get()); 210 | rot.Normalize(); 211 | obstacle->SetPos(ChVector3d(o_posX, o_posY, o_posZ)); 212 | obstacle->SetRot(rot); 213 | 214 | system->AddBody(obstacle); 215 | } 216 | } 217 | 218 | void AddFixedObstacles(ChSystem* system) { 219 | // Create contact material, of appropriate type. Use default properties 220 | std::shared_ptr material; 221 | switch (NSC_SMC) { 222 | case ChContactMethod::NSC: { 223 | auto matNSC = chrono_types::make_shared(); 224 | // Change NSC material properties as desired 225 | material = matNSC; 226 | break; 227 | } 228 | case ChContactMethod::SMC: { 229 | auto matSMC = chrono_types::make_shared(); 230 | // Change SMC material properties as desired 231 | material = matSMC; 232 | break; 233 | } 234 | } 235 | 236 | double radius = 3; 237 | double length = 20; 238 | auto obstacle = chrono_types::make_shared(ChAxis::Y, radius, length, 2000, true, true, material); 239 | 240 | obstacle->SetPos(ChVector3d(-20, 0, -2.7)); 241 | obstacle->SetFixed(true); 242 | 243 | system->AddBody(obstacle); 244 | 245 | for (int i = 0; i < 8; ++i) { 246 | auto stoneslab = chrono_types::make_shared(1.0, 5.0, 0.5, 2000, true, true, material); 247 | stoneslab->SetPos(ChVector3d(-1.2 * i + 22, -1.5, -0.25)); 248 | stoneslab->SetRot(QuatFromAngleAxis(15 * CH_DEG_TO_RAD, VECT_Y)); 249 | stoneslab->SetFixed(true); 250 | system->AddBody(stoneslab); 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /Chrono/FEA/FEA_cable_collide_2.cpp: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // PROJECT CHRONO - http://projectchrono.org 3 | // 4 | // Copyright (c) 2014 projectchrono.org 5 | // All right reserved. 6 | // 7 | // Use of this source code is governed by a BSD-style license that can be found 8 | // in the LICENSE file at the top level of the distribution and at 9 | // http://projectchrono.org/license-chrono.txt. 10 | // 11 | // ============================================================================= 12 | // Author: Alessandro Tasora 13 | // ============================================================================= 14 | // 15 | // Create a falling and colliding cable using FEA module (FEA tutorial n.2) 16 | // 17 | // This model is made with N elements of ChElementBeamEuler type. They are 18 | // added to a ChMesh and then the first cable is connected to the absolute 19 | // reference using a joint. 20 | // 21 | // A simple ChContactSurfaceNodeCloud is used to provide collision against 22 | // the floor. 23 | // 24 | // The cable falls under the action of gravity alone, acting in the negative 25 | // Y (up) direction. 26 | // 27 | // The simulation is animated with Irrlicht. 28 | // 29 | // ============================================================================= 30 | 31 | #include 32 | #include 33 | 34 | #include "chrono/physics/ChBodyEasy.h" 35 | #include "chrono/physics/ChLinkMate.h" 36 | #include "chrono/physics/ChSystemSMC.h" 37 | #include "chrono/solver/ChIterativeSolverLS.h" 38 | #include "chrono_irrlicht/ChVisualSystemIrrlicht.h" 39 | 40 | #include "chrono/fea/ChBuilderBeam.h" 41 | #include "chrono/fea/ChContactSurfaceMesh.h" 42 | #include "chrono/fea/ChContactSurfaceNodeCloud.h" 43 | #include "chrono/fea/ChElementBeamEuler.h" 44 | #include "chrono/fea/ChMesh.h" 45 | #include "chrono/assets/ChVisualShapeFEA.h" 46 | 47 | using namespace chrono; 48 | using namespace chrono::irrlicht; 49 | using namespace chrono::fea; 50 | using namespace irr; 51 | 52 | int main(int argc, char* argv[]) { 53 | // 0. Set the path to the Chrono data folder 54 | 55 | SetChronoDataPath(CHRONO_DATA_DIR); 56 | 57 | // 1. Create the physical system that will handle all finite elements and constraints. 58 | 59 | // NOTE that we need contact in FEA, so we use the ChSystemSMC, that uses SMC penalty in contacts 60 | ChSystemSMC system; 61 | 62 | system.SetCollisionSystemType(ChCollisionSystem::Type::BULLET); 63 | 64 | // 2. Create the mesh that will contain the finite elements, and add it to the system 65 | 66 | auto mesh = chrono_types::make_shared(); 67 | 68 | system.Add(mesh); 69 | 70 | //// ------------------------------------------------------------------------- 71 | //// EXERCISE 1 72 | //// 73 | //// Use Euler-Bernoulli beams to make a hanging cable, exactly as in 74 | //// the FEA_cable_collide_1.cpp, but with ChElementBeamEuler elements 75 | //// instead of ChElementCableANCF. 76 | //// The ChElementBeamEuler beams are more sophisticated as they can also 77 | //// simulate torsion and shear, and off-center shear effects. 78 | //// Just use the same for() loops of the previous demo, but use these hints: 79 | //// Hint: when creating the section material, in 3., remember that 80 | //// ChElementBeamEuler needs a ChBeamSectionAdvanced material. 81 | //// Hint: when creating the nodes, in 4., the nodes 82 | //// for ChElementBeamEuler must be of ChNodeFEAxyzrot class; 83 | //// i.e. each node has coordinates of type: {position, rotation}, 84 | //// where X axis of rotated system is the direction of the beam, 85 | //// Y and Z are the section plane. 86 | //// Hint: when creating the elements, in 5., use ChElemetBeamEuler 87 | //// Hint: when creating the truss-node constraint, in 6., use ChLinkMateSpherical 88 | //// 89 | //// ------------------------------------------------------------------------- 90 | 91 | // 3. Create a material for the beam finite elements. 92 | // TO DO ... 93 | 94 | // 4. Create the nodes 95 | // TO DO .... 96 | 97 | // 5. Create the elements 98 | // TO DO .... 99 | 100 | // 6. Add constraints 101 | // TO DO .... 102 | 103 | // 7. Add a collision mesh to the skin of the finite element mesh 104 | 105 | // - Create a ChContactMaterialSMC , it must be assigned to FEA 106 | // meshes and rigid bodies. The ChSystemSMC requires it! 107 | // - Create a ChContactSurfaceNodeCloud and add to the FEA mesh. 108 | // This is the easiest representation of a FEA contact surface: it 109 | // simply creates contact spheres per each node. So, no edge-edge cases 110 | // can be detected between elements though, but it is enough for 111 | // dense finite elements meshes that collide with large objects. 112 | 113 | // Create a surface material to be shared with some objects 114 | auto surfmaterial = chrono_types::make_shared(); 115 | surfmaterial->SetYoungModulus(6e4); 116 | surfmaterial->SetFriction(0.3f); 117 | surfmaterial->SetRestitution(0.2f); 118 | surfmaterial->SetAdhesion(0); 119 | 120 | // Create the contact surface and add to the mesh, using our SMC contact material 121 | auto contactcloud = chrono_types::make_shared(surfmaterial); 122 | mesh->AddContactSurface(contactcloud); 123 | 124 | // Must use this to 'populate' the contact surface use larger point size to match beam section radius 125 | contactcloud->AddAllNodes(*mesh, 0.01); 126 | 127 | // 8. Create a collision plane, as a huge box 128 | 129 | auto floor = chrono_types::make_shared(4, 0.2, 4, // x,y,z size 130 | 1000, // density 131 | true, // visible 132 | true, // collide 133 | surfmaterial // contact material 134 | ); 135 | 136 | system.Add(floor); 137 | 138 | floor->SetFixed(true); 139 | floor->SetPos(ChVector3d(0, -0.1, 0)); 140 | 141 | // 9. Make the finite elements visible in the 3D view 142 | 143 | // - FEA fisualization can be managed via an easy 144 | // ChVisualizationFEAmesh helper class. 145 | // (Alternatively you could bypass this and output .dat 146 | // files at each step, ex. for VTK or Matalb postprocessing) 147 | // - This will automatically update a triangle mesh (a ChVisualShapeTriangleMesh 148 | // asset that is internally managed) by setting proper 149 | // coordinates and vertex colours as in the FEA elements. 150 | // - Such triangle mesh can be rendered by Irrlicht or POVray or whatever 151 | // postprocessor that can handle a coloured ChVisualShapeTriangleMesh). 152 | // - Do not forget AddAsset() at the end! 153 | 154 | auto visualizebeamA = chrono_types::make_shared(); 155 | visualizebeamA->SetFEMdataType(ChVisualShapeFEA::DataType::ANCF_BEAM_AX); 156 | visualizebeamA->SetColormapRange(-0.005, 0.005); 157 | visualizebeamA->SetSmoothFaces(true); 158 | visualizebeamA->SetWireframe(false); 159 | mesh->AddVisualShapeFEA(visualizebeamA); 160 | 161 | auto visualizebeamB = chrono_types::make_shared(); 162 | visualizebeamB->SetFEMglyphType(ChVisualShapeFEA::GlyphType::NODE_DOT_POS); 163 | visualizebeamB->SetFEMdataType(ChVisualShapeFEA::DataType::NONE); 164 | visualizebeamB->SetSymbolsThickness(0.006); 165 | visualizebeamB->SetSymbolsScale(0.005); 166 | visualizebeamB->SetZbufferHide(false); 167 | mesh->AddVisualShapeFEA(visualizebeamB); 168 | 169 | // 10. Configure the solver and timestepper 170 | 171 | // - the default SOLVER_SOR of Chrono is not able to manage stiffness matrices 172 | // as required by FEA! we must switch to a different solver. 173 | // - We pick the SOLVER_MINRES solver and we configure it. 174 | // - Note that if you build the MKL module, you could use the more precise MKL solver. 175 | 176 | // Change solver 177 | auto solver = chrono_types::make_shared(); 178 | solver->SetMaxIterations(200); 179 | solver->SetTolerance(1e-10); 180 | solver->EnableWarmStart(true); 181 | system.SetSolver(solver); 182 | 183 | // Change integrator: 184 | // system.SetTimestepperType(ChTimestepper::Type::EULER_IMPLICIT_LINEARIZED); // default: fast, 1st order 185 | // system.SetTimestepperType(ChTimestepper::Type::HHT); // precise, slower, might iterate each step 186 | 187 | // 11. Prepare visualization with Irrlicht 188 | // Note that Irrlicht uses left-handed frames with Y up. 189 | 190 | // Create the Irrlicht application and set-up the camera. 191 | auto vis = chrono_types::make_shared(); 192 | vis->SetWindowSize(1024, 768); 193 | vis->SetWindowTitle("FEA cable collide demo"); 194 | vis->Initialize(); 195 | vis->AddLogo(); 196 | vis->AddSkyBox(); 197 | vis->AddTypicalLights(); 198 | vis->AddCamera(ChVector3d(0.1f, 0.2f, -2.0f)); 199 | vis->EnableContactDrawing(ContactsDrawMode::CONTACT_FORCES); 200 | vis->SetSymbolScale(0.1); 201 | vis->AttachSystem(&system); 202 | 203 | // 12. Perform the simulation. 204 | 205 | while (vis->Run()) { 206 | // Initialize the graphical scene. 207 | vis->BeginScene(); 208 | 209 | // Render all visualization objects. 210 | vis->Render(); 211 | 212 | // Draw an XZ grid at the global origin to add in visualization. 213 | tools::drawGrid(vis.get(), 0.1, 0.1, 20, 20, ChCoordsys<>(ChVector3d(0, 0, 0), QuatFromAngleX(CH_PI_2)), 214 | ChColor(0.3f, 0.4f, 0.4f), true); 215 | 216 | // Finalize the graphical scene. 217 | vis->EndScene(); 218 | 219 | // Advance simulation by one step. 220 | system.DoStepDynamics(0.001); 221 | } 222 | 223 | return 0; 224 | } 225 | -------------------------------------------------------------------------------- /PyChrono/FEA/FEA_cable_collide_1_solution.py: -------------------------------------------------------------------------------- 1 | # ============================================================================= 2 | # PROJECT CHRONO - http:#projectchrono.org 3 | # 4 | # Copyright (c) 2014 projectchrono.org 5 | # All right reserved. 6 | # 7 | # Use of this source code is governed by a BSD-style license that can be found 8 | # in the LICENSE file at the top level of the distribution and at 9 | # http:#projectchrono.org/license-chrono.txt. 10 | # 11 | # ============================================================================= 12 | # Author: Simone Benatti 13 | # ============================================================================= 14 | # 15 | # Create a falling cable using FEA module (FEA tutorial n.1) 16 | # 17 | # This cable is made with N beam elements of ChElementANCFcable type. They are 18 | # added to a ChMesh and then the first node is connected to the absolute 19 | # reference using a constraint. 20 | # 21 | # The cable falls under the action of gravity alone, acting in the negative 22 | # Y (up) direction. 23 | # 24 | # The simulation is animated with Irrlicht. 25 | # 26 | # ============================================================================= 27 | 28 | import pychrono as chrono 29 | import pychrono.fea as fea 30 | import pychrono.irrlicht as chronoirr 31 | 32 | # 0. Set the path to the Chrono data folder 33 | CHRONO_DATA_DIR = "E:/Repositories/chrono/data/" 34 | chrono.SetChronoDataPath(CHRONO_DATA_DIR) 35 | 36 | # 1. Create the physical system that will handle all finite elements and constraints. 37 | 38 | # Specify the gravitational acceleration vector, consistent with the 39 | # global reference frame having Y up (ISO system). 40 | system = chrono.ChSystemNSC() 41 | system.SetGravitationalAcceleration(chrono.ChVector3d(0, -9.81, 0)) 42 | 43 | 44 | # 2. Create the mesh that will contain the finite elements, and add it to the system 45 | 46 | mesh = fea.ChMesh() 47 | 48 | system.Add(mesh) 49 | 50 | 51 | # 3. Create a material for the beam finite elements. 52 | 53 | # Note that each FEA element type requires some corresponding 54 | # type of material. Here we will use ChElementCableANCF elements: 55 | # they use a material of type ChBeamSectionCable, so let's do 56 | 57 | beam_material = fea.ChBeamSectionCable() 58 | beam_material.SetDiameter(0.01) 59 | beam_material.SetYoungModulus(0.01e9) 60 | beam_material.SetBeamRaleyghDamping(0.01) 61 | 62 | 63 | # 4. Create the nodes 64 | 65 | # - We use a simple for() loop to create nodes along the cable. 66 | # - Nodes for ChElementCableANCF must be of ChNodeFEAxyzD class 67 | # i.e. each node has 6 coordinates: position, direction, where 68 | # direction is the tangent to the cable. 69 | # - Each node must be added to the mesh, ex. mesh.Add(my_node) 70 | # - To make things easier in the following, we store node pointers 71 | # into an optional 'beam_nodes' array, i.e. a std::vector<>, later we 72 | # can use such array for easy creation of elements between the nodes. 73 | 74 | beam_nodes = [] 75 | 76 | length = 1.2 # beam length, in meters 77 | N_nodes = 16 78 | for i_ni in range(N_nodes) : 79 | # i-th node position 80 | position = chrono.ChVector3d(length * (i_ni / (N_nodes - 1)), # node position, x 81 | 0.5, # node position, y 82 | 0) # node position, z 83 | 84 | # i-th node direction 85 | direction = chrono.ChVector3d(1.0, 0, 0) 86 | 87 | # create the node 88 | node = fea.ChNodeFEAxyzD(position, direction) 89 | 90 | # add it to mesh 91 | mesh.AddNode(node) 92 | 93 | # add it to the auxiliary beam_nodes 94 | beam_nodes.append(node) 95 | 96 | 97 | 98 | # 5. Create the elements 99 | 100 | # - We use a simple for() loop to create elements between the 101 | # nodes that we already created. 102 | # - Each element must be set with the ChBeamSectionCable material 103 | # that we already created 104 | # - Each element must be added to the mesh, ex. mesh.Add(my_element) 105 | 106 | for ie in range(N_nodes - 1) : 107 | # create the element 108 | element = fea.ChElementCableANCF() 109 | 110 | # set the connected nodes (pick two consecutive nodes in our beam_nodes container) 111 | element.SetNodes(beam_nodes[ie], beam_nodes[ie + 1]) 112 | 113 | # set the material 114 | element.SetSection(beam_material) 115 | 116 | # add it to mesh 117 | mesh.AddElement(element) 118 | 119 | 120 | 121 | # 6. Add constraints 122 | 123 | # - Constraints can be applied to FEA nodes 124 | # - For the ChNodeFEAxyzD there are specific constraints that 125 | # can be used to connect them to a ChBody, namely 126 | # ChLinkNodeFrame and ChLinkNodeSlopeFrame 127 | # - To attach one end of the beam to the ground, we need a 128 | # 'truss' ChBody that is fixed. 129 | # - Note. An alternative, only when the node must be fixed 130 | # to absolute reference, is not using constraints, and just 131 | # use: beam_nodes[0].SetFixed(True) (but would fix also dir) 132 | 133 | truss = chrono.ChBody() 134 | truss.SetFixed(True) 135 | system.Add(truss) 136 | 137 | # lock an end of the wire to the truss 138 | constraint_pos = fea.ChLinkNodeFrame() 139 | constraint_pos.Initialize(beam_nodes[0], truss) 140 | system.Add(constraint_pos) 141 | 142 | 143 | ## ------------------------------------------------------------------------- 144 | ## EXERCISE 1a 145 | ## 146 | ## Add a cylinder. 147 | ## Suggested size: 0.02 radius, 0.1 height, density:1000. 148 | ## Hint: use the ChBodyEasyCylinder to make the cylinder, pass size as 149 | ## parameters in construction. 150 | ## 151 | ## ------------------------------------------------------------------------- 152 | 153 | # create the cylinder 154 | cylinder = chrono.ChBodyEasyCylinder( 155 | chrono.ChAxis_Y, # cylinder alignment 156 | 0.02, # radius 157 | 0.1, # height 158 | 1000, # density (used to auto-set inertia, mass) 159 | True, # do collide 160 | True) # do visualize 161 | 162 | # move cylinder to end of beam 163 | cylinder.SetPos( beam_nodes[-1].GetPos() + chrono.ChVector3d(0, -0.05, 0) ) 164 | 165 | # add it to the system 166 | system.Add(cylinder) 167 | 168 | ## ------------------------------------------------------------------------- 169 | ## EXERCISE 1b 170 | ## 171 | ## Attach the cylinder to the free end of the cable. 172 | ## Hint: use the ChLinkNodeFrame to connect the cylinder and the end node. 173 | ## 174 | ## ------------------------------------------------------------------------- 175 | 176 | # lock an end of the wire to the cylinder 177 | constraint_cyl = fea.ChLinkNodeFrame() 178 | constraint_cyl.Initialize(beam_nodes[-1], cylinder) 179 | system.Add(constraint_cyl) 180 | 181 | 182 | # 7. Make the finite elements visible in the 3D view 183 | 184 | # - FEA fisualization can be managed via an easy 185 | # ChVisualizationFEAmesh helper class. 186 | # (Alternatively you could bypass this and output .dat 187 | # files at each step, ex. for VTK or Matalb postprocessing) 188 | # - This will automatically update a triangle mesh (a ChVisualShapeTriangleMesh 189 | # asset that is internally managed) by setting proper 190 | # coordinates and vertex colours as in the FEA elements. 191 | # - Such triangle mesh can be rendered by Irrlicht or POVray or whatever 192 | # postprocessor that can handle a coloured ChVisualShapeTriangleMesh). 193 | # - Do not forget AddAsset() at the end! 194 | 195 | mvisualizebeamA = chrono.ChVisualShapeFEA(mesh) 196 | mvisualizebeamA.SetFEMdataType(chrono.ChVisualShapeFEA.DataType_ANCF_BEAM_AX) 197 | mvisualizebeamA.SetColorscaleMinMax(-0.005, 0.005) 198 | mvisualizebeamA.SetSmoothFaces(True) 199 | mvisualizebeamA.SetWireframe(False) 200 | mesh.AddVisualShapeFEA(mvisualizebeamA) 201 | 202 | mvisualizebeamC = chrono.ChVisualShapeFEA(mesh) 203 | mvisualizebeamC.SetFEMglyphType(chrono.ChVisualShapeFEA.GlyphType_NODE_DOT_POS) 204 | mvisualizebeamC.SetFEMdataType(chrono.ChVisualShapeFEA.DataType_NONE) 205 | mvisualizebeamC.SetSymbolsThickness(0.006) 206 | mvisualizebeamC.SetSymbolsScale(0.005) 207 | mvisualizebeamC.SetZbufferHide(False) 208 | mesh.AddVisualShapeFEA(mvisualizebeamC) 209 | 210 | 211 | # 8. Configure the solver and timestepper 212 | 213 | # - the default SOLVER_SOR of Chrono is not able to manage stiffness matrices 214 | # as required by FEA! we must switch to a different solver. 215 | # - We pick the SOLVER_MINRES solver and we configure it. 216 | # - Note that if you build the MKL module, you could use the more precise MKL solver. 217 | 218 | # Change solver 219 | solver = chrono.ChSolverMINRES() 220 | solver.SetMaxIterations(200) 221 | solver.SetTolerance(1e-10) 222 | solver.EnableWarmStart(True) 223 | system.SetSolver(solver) 224 | 225 | # Change integrator: 226 | system.SetTimestepperType(chrono.ChTimestepper.Type_EULER_IMPLICIT_LINEARIZED) # default: fast, 1st order 227 | # system.SetTimestepperType(ChTimestepper::Type::HHT) # precise, slower, might iterate each step 228 | 229 | 230 | # 9. Prepare visualization with Irrlicht 231 | # Note that Irrlicht uses left-handed frames with Y up. 232 | 233 | # Create the Irrlicht application and set-up the camera. 234 | vis = chronoirr.ChVisualSystemIrrlicht() 235 | vis.SetWindowSize(1024, 768) 236 | vis.SetWindowTitle("FEA cable collide demo") 237 | vis.Initialize() 238 | vis.AddLogo() 239 | vis.AddSkyBox() 240 | vis.AddTypicalLights() 241 | vis.AddCamera(chrono.ChVector3d(0.1, 0.2, -2.0)) 242 | vis.SetSymbolScale(0.1) 243 | vis.AttachSystem(system) 244 | 245 | 246 | # 10. Perform the simulation. 247 | 248 | # Specify the step-size. 249 | step_size = 0.001 250 | realtime_timer = chrono.ChRealtimeStepTimer() 251 | 252 | while vis.Run(): 253 | vis.BeginScene() 254 | 255 | # Render Chrono item assets 256 | vis.Render() 257 | 258 | # Draw an XZ grid at the global origin to add in visualization. 259 | chronoirr.drawGrid( 260 | vis, 0.1, 0.1, 20, 20, 261 | chrono.ChCoordsysd(chrono.ChVector3d(0, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2)), 262 | chrono.ChColor(0.4, 0.7, 0.4), True) 263 | 264 | vis.EndScene() 265 | 266 | ## Advance simulation by one step 267 | system.DoStepDynamics(step_size) 268 | 269 | # Spin in place for real time to catch up 270 | realtime_timer.Spin(step_size) 271 | 272 | -------------------------------------------------------------------------------- /PyChrono/slider-crank/slider_crank_2.py: -------------------------------------------------------------------------------- 1 | ## ============================================================================= 2 | ## PROJECT CHRONO - http:##projectchrono.org 3 | ## 4 | ## Copyright (c) 2014 projectchrono.org 5 | ## All right reserved. 6 | ## 7 | ## Use of this source code is governed by a BSD-style license that can be found 8 | ## in the LICENSE file at the top level of the distribution and at 9 | ## http://projectchrono.org/license-chrono.txt. 10 | ## 11 | ## ============================================================================= 12 | ## Author: Simone Benatti 13 | ## ============================================================================= 14 | ## 15 | ## Slider-crank Chrono tutorial (model 2) 16 | ## 17 | ## This model is a 3-body slider-crank consisting of crank, slider and connecting 18 | ## rod bodies. The crank is connected to ground with a revolute joint and the 19 | ## slider is connected to ground through a prismatic joint. The connecting rod 20 | ## connects to the crank through a spherical joint and to the slider through a 21 | ## universal joint. 22 | ## 23 | ## The crank body is driven at constant angular speed, under the action of gravity, 24 | ## acting in the negative Z direction. 25 | ## 26 | ## An additional spherical body, constrained to move along the global X axis 27 | ## through a prismatic joint and connected to ground with a translational spring 28 | ## damper, interacts through contact with the slider body. 29 | ## 30 | ## The simulation is animated with Irrlicht. 31 | ## 32 | ## ============================================================================= 33 | 34 | import pychrono as chrono 35 | from pychrono import irrlicht as chronoirr 36 | 37 | ## 0. Set the path to the Chrono data folder 38 | chrono.SetChronoDataPath('E:/Repositories/chrono/data/') 39 | 40 | ## 1. Create the physical system that will handle all bodies and constraints. 41 | 42 | ## Specify the gravitational acceleration vector, consistent with the 43 | ## global reference frame having Z up. 44 | system = chrono.ChSystemNSC() 45 | system.SetGravitationalAcceleration(chrono.ChVector3d(0, 0, -9.81)) 46 | 47 | ## 2. Create the rigid bodies of the slider-crank mechanical system. 48 | ## For each body, specify: 49 | ## - a unique identifier 50 | ## - mass and moments of inertia 51 | ## - position and orientation of the (centroidal) body frame 52 | ## - visualization assets (defined with respect to the body frame) 53 | 54 | ## Ground 55 | ground = chrono.ChBody() 56 | system.AddBody(ground) 57 | ground.SetIdentifier(-1) 58 | ground.SetName("ground") 59 | ground.SetFixed(True) 60 | 61 | cyl_g = chrono.ChVisualShapeCylinder(0.03, 0.4) 62 | cyl_g.SetColor(chrono.ChColor(0.6, 0.6, 0.2)) 63 | ground.AddVisualShape(cyl_g) 64 | 65 | ## Crank 66 | crank = chrono.ChBody() 67 | system.AddBody(crank) 68 | crank.SetIdentifier(1) 69 | crank.SetName("crank") 70 | crank.SetMass(1.0) 71 | crank.SetInertiaXX(chrono.ChVector3d(0.005, 0.1, 0.1)) 72 | crank.SetPos(chrono.ChVector3d(-1, 0, 0)) 73 | crank.SetRot(chrono.ChQuaterniond(1, 0, 0, 0)) 74 | 75 | box_c = chrono.ChVisualShapeBox(1.9, 0.1, 0.1) 76 | crank.AddVisualShape(box_c) 77 | 78 | cyl_c = chrono.ChVisualShapeCylinder(0.05, 0.2) 79 | crank.AddVisualShape(cyl_c, chrono.ChFramed(chrono.ChVector3d(1, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2))) 80 | 81 | sph_c = chrono.ChVisualShapeSphere(0.05) 82 | sph_c.SetColor(chrono.ChColor(0.6, 0.2, 0.2)) 83 | crank.AddVisualShape(sph_c, chrono.ChFramed(chrono.ChVector3d(-1, 0, 0))) 84 | 85 | ## Slider 86 | slider = chrono.ChBody() 87 | system.AddBody(slider) 88 | slider.SetIdentifier(2) 89 | slider.SetName("slider") 90 | slider.SetMass(1.0) 91 | slider.SetInertiaXX(chrono.ChVector3d(0.05, 0.05, 0.05)) 92 | slider.SetPos(chrono.ChVector3d(2, 0, 0)) 93 | slider.SetRot(chrono.ChQuaterniond(1, 0, 0, 0)) 94 | 95 | box_s = chrono.ChVisualShapeBox(0.4, 0.2, 0.2) 96 | box_s.SetColor(chrono.ChColor(0.2, 0.2, 0.6)) 97 | slider.AddVisualShape(box_s) 98 | 99 | cyl_s = chrono.ChVisualShapeCylinder(0.03, 0.4) 100 | cyl_s.SetColor(chrono.ChColor(0.2, 0.2, 0.6)) 101 | slider.AddVisualShape(cyl_s, chrono.ChFramed(chrono.VNULL, chrono.QuatFromAngleX(chrono.CH_PI_2))) 102 | 103 | ## Connecting rod 104 | rod = chrono.ChBody() 105 | system.AddBody(rod) 106 | rod.SetIdentifier(3) 107 | rod.SetName("rod") 108 | rod.SetMass(0.5) 109 | rod.SetMass(0.5) 110 | rod.SetInertiaXX(chrono.ChVector3d(0.005, 0.1, 0.1)) 111 | rod.SetPos(chrono.ChVector3d(0, 0, 0)) 112 | rod.SetRot(chrono.ChQuaterniond(1, 0, 0, 0)) 113 | 114 | box_r = chrono.ChVisualShapeBox(4, 0.1, 0.1) 115 | rod.AddVisualShape(box_r) 116 | 117 | cyl_r = chrono.ChVisualShapeCylinder(0.03, 0.4) 118 | cyl_r.SetColor(chrono.ChColor(0.2, 0.6, 0.2)) 119 | rod.AddVisualShape(cyl_r, chrono.ChFramed(chrono.ChVector3d(2, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2))); 120 | 121 | #### ------------------------------------------------------------------------- 122 | #### EXERCISE 2.1 123 | #### Enable contact on the slider body and specify contact geometry 124 | #### The contact shape attached to the slider body should be a box with the 125 | #### same dimensions as the visualization asset, centered at the body origin. 126 | #### Use a coefficient of friction of 0.4. 127 | #### ------------------------------------------------------------------------- 128 | 129 | ## TO DO 130 | 131 | 132 | #### ------------------------------------------------------------------------- 133 | #### EXERCISE 2.2 134 | #### Create a new body, with a spherical shape (radius 0.2), used both as 135 | #### visualization asset and contact shape (mu = 0.4). This body should have: 136 | #### mass: 1 137 | #### moments of inertia: I_xx = I_yy = I_zz = 0.02 138 | #### initial location: (5.5, 0, 0) 139 | #### ------------------------------------------------------------------------- 140 | 141 | ## TO DO 142 | 143 | 144 | ## 3. Create joint constraints. 145 | ## All joint frames are specified in the global frame. 146 | 147 | ## Define two quaternions representing: 148 | ## - a rotation of -90 degrees around x (z2y) 149 | ## - a rotation of +90 degrees around y (z2x) 150 | z2y = chrono.ChQuaterniond() 151 | z2x = chrono.ChQuaterniond() 152 | z2y.SetFromAngleX(-chrono.CH_PI / 2) 153 | z2x.SetFromAngleY(chrono.CH_PI / 2) 154 | 155 | ## Create a ChFunction object that always returns the constant value PI/2. 156 | fun = chrono.ChFunctionConst() 157 | fun.Set_yconst(chrono.CH_PI) 158 | 159 | ## Motor between ground and crank. 160 | ## Note that this also acts as a revolute joint (i.e. it enforces the same 161 | ## kinematic constraints as a revolute joint). As before, we apply the 'z2y' 162 | ## rotation to align the rotation axis with the Y axis of the global frame. 163 | engine_ground_crank = chrono.ChLinkMotorRotationSpeed() 164 | engine_ground_crank.SetName("engine_ground_crank") 165 | engine_ground_crank.Initialize(ground, crank, chrono.ChFramed(chrono.ChVector3d(0, 0, 0), z2y)) 166 | engine_ground_crank.SetSpeedFunction(fun) 167 | system.AddLink(engine_ground_crank) 168 | 169 | ## Prismatic joint between ground and slider. 170 | ## The translational axis of a prismatic joint is along the Z axis of the 171 | ## specified joint coordinate system. Here, we apply the 'z2x' rotation to 172 | ## align it with the X axis of the global reference frame. 173 | prismatic_ground_slider = chrono.ChLinkLockPrismatic() 174 | prismatic_ground_slider.SetName("prismatic_ground_slider") 175 | prismatic_ground_slider.Initialize(ground, slider, chrono.ChFramed(chrono.ChVector3d(2, 0, 0), z2x)) 176 | system.AddLink(prismatic_ground_slider) 177 | 178 | ## Spherical joint between crank and rod 179 | spherical_crank_rod = chrono.ChLinkLockSpherical() 180 | spherical_crank_rod.SetName("spherical_crank_rod") 181 | spherical_crank_rod.Initialize(crank, rod, chrono.ChFramed(chrono.ChVector3d(-2, 0, 0), chrono.QUNIT)) 182 | system.AddLink(spherical_crank_rod) 183 | 184 | ## Universal joint between rod and slider. 185 | ## The "cross" of a universal joint is defined using the X and Y axes of the 186 | ## specified joint coordinate frame. Here, we apply the 'z2x' rotation so that 187 | ## the cross is aligned with the Z and Y axes of the global reference frame. 188 | universal_rod_slider = chrono.ChLinkUniversal() 189 | universal_rod_slider.SetName("universal_rod_slider") 190 | universal_rod_slider.Initialize(rod, slider, chrono.ChFramed(chrono.ChVector3d(2, 0, 0), z2x)) 191 | system.AddLink(universal_rod_slider) 192 | 193 | #### ------------------------------------------------------------------------- 194 | #### EXERCISE 2.3 195 | #### Add a prismatic joint between ground and ball to constrain the ball's 196 | #### motion to the global X axis. 197 | #### ------------------------------------------------------------------------- 198 | 199 | ## TODO 200 | 201 | 202 | #### ------------------------------------------------------------------------- 203 | #### EXERCISE 2.4 204 | #### Add a spring-damper (ChLinkTSDA) between ground and the ball. 205 | #### This element should connect the center of the ball with the global point 206 | #### (6.5, 0, 0). Set a spring constant of 50 and a spring free length of 1. 207 | #### Set a damping coefficient of 5. 208 | #### ------------------------------------------------------------------------- 209 | 210 | ## TODO 211 | 212 | 213 | ## 4. Write the system hierarchy to the console (default log output destination) 214 | ####system.ShowHierarchy(chrono.GetLog()) 215 | 216 | ## 5. Prepare visualization with Irrlicht 217 | ## Note that Irrlicht uses left-handed frames with Y up. 218 | 219 | ## Create the Irrlicht application and set-up the camera. 220 | vis = chronoirr.ChVisualSystemIrrlicht() 221 | vis.AttachSystem(system) 222 | vis.SetWindowSize(1024,768) 223 | vis.SetWindowTitle('Slider-Crank Demo 2') 224 | vis.SetCameraVertical(chrono.CameraVerticalDir_Z) 225 | vis.Initialize() 226 | vis.AddLogo(chrono.GetChronoDataFile('logo_pychrono_alpha.png')) 227 | vis.AddSkyBox() 228 | vis.AddCamera(chrono.ChVector3d(2, -5, 0), chrono.ChVector3d(2, 0, 0)) 229 | vis.AddTypicalLights() 230 | 231 | ## 6. Perform the simulation. 232 | 233 | ## Specify the step-size. 234 | step_size = 0.01 235 | realtime_timer = chrono.ChRealtimeStepTimer() 236 | 237 | while (vis.Run()): 238 | vis.BeginScene() 239 | 240 | # Render Chrono item assets 241 | vis.Render() 242 | 243 | ## Draw an XZ grid at the global origin to add in visualization 244 | chronoirr.drawGrid( 245 | vis, 1, 1, 20, 20, 246 | chrono.ChCoordsysd(chrono.ChVector3d(0, 0, 0), chrono.QuatFromAngleX(chrono.CH_PI_2)), 247 | chrono.ChColor(0.4, 0.7, 0.4), True) 248 | chronoirr.drawAllCOGs(vis, 1) 249 | 250 | vis.EndScene() 251 | 252 | ## Advance simulation by one step 253 | system.DoStepDynamics(step_size) 254 | 255 | # Spin in place for real time to catch up 256 | realtime_timer.Spin(step_size) 257 | -------------------------------------------------------------------------------- /Chrono/multicore/cratering_solution_1.cpp: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // PROJECT CHRONO - http://projectchrono.org 3 | // 4 | // Copyright (c) 2014 projectchrono.org 5 | // All right reserved. 6 | // 7 | // Use of this source code is governed by a BSD-style license that can be found 8 | // in the LICENSE file at the top level of the distribution and at 9 | // http://projectchrono.org/license-chrono.txt. 10 | // 11 | // ============================================================================= 12 | // Author: Radu Serban 13 | // ============================================================================= 14 | // 15 | // Chrono::Multicore tutorial. 16 | // 17 | // The model simulated here consists of a spherical projectile dropped in a 18 | // bed of granular material, using either penalty or complementarity method for 19 | // frictional contact. 20 | // 21 | // SOLUTION for EXERCISE 1: 22 | // - create granular material (complete implementation of CreateObjects) 23 | // - set numbers of bins for broad-phase collision 24 | // 25 | // The global reference frame has Z up. 26 | // All units SI. 27 | // ============================================================================= 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include "chrono/ChConfig.h" 34 | #include "chrono/utils/ChUtilsCreators.h" 35 | #include "chrono/utils/ChUtilsGenerators.h" 36 | 37 | #include "chrono_multicore/physics/ChSystemMulticore.h" 38 | 39 | #ifdef CHRONO_VSG 40 | #include "chrono_vsg/ChVisualSystemVSG.h" 41 | using namespace chrono::vsg3d; 42 | #endif 43 | 44 | using namespace chrono; 45 | 46 | using std::cout; 47 | using std::endl; 48 | using std::flush; 49 | 50 | // ----------------------------------------------------------------------------- 51 | // Problem definitions 52 | // ----------------------------------------------------------------------------- 53 | 54 | // Desired number of OpenMP threads (will be clamped to maximum available) 55 | int threads = 4; 56 | 57 | // Parameters for the granular material 58 | int tag_particles = 0; // all particles wilkl have tag at least this value 59 | double r_g = 2e-3; 60 | double rho_g = 2500; 61 | double vol_g = (4.0 / 3) * CH_PI * r_g * r_g * r_g; 62 | double mass_g = rho_g * vol_g; 63 | ChVector3d inertia_g = 0.4 * mass_g * r_g * r_g * ChVector3d(1, 1, 1); 64 | 65 | float Y_g = 1e7f; 66 | float mu_g = 0.3f; 67 | float cr_g = 0.1f; 68 | 69 | // Parameters for the falling ball 70 | double R_b = 1.5e-2; 71 | double rho_b = 700; 72 | double vol_b = (4.0 / 3) * CH_PI * R_b * R_b * R_b; 73 | double mass_b = rho_b * vol_b; 74 | ChVector3d inertia_b = 0.4 * mass_b * R_b * R_b * ChVector3d(1, 1, 1); 75 | 76 | float Y_b = 1e8f; 77 | float mu_b = 0.3f; 78 | float cr_b = 0.1f; 79 | 80 | // Parameters for the containing bin 81 | double hDimX = 4e-2; // length in x direction 82 | double hDimY = 4e-2; // depth in y direction 83 | double hDimZ = 4e-2; // height in z direction 84 | double hThickness = 0.5e-2; // wall thickness 85 | 86 | float Y_c = 2e6f; 87 | float mu_c = 0.3f; 88 | float cr_c = 0.1f; 89 | 90 | // Drop height and vertical velocity 91 | double initial_height = 0.1; 92 | double initial_velocity = 0; 93 | 94 | // ----------------------------------------------------------------------------- 95 | // Create the container (five boxes) 96 | // ----------------------------------------------------------------------------- 97 | void CreateContainer(ChSystemMulticore* system) { 98 | // Create a material for the container 99 | auto material_c = chrono_types::make_shared(); 100 | material_c->SetFriction(mu_c); 101 | 102 | // Create the container. This utility function creates the container body (fixed to "ground") 103 | // and sets both the contact and visualization shapes. 104 | utils::CreateBoxContainer(system, material_c, ChVector3d(2 * hDimX, 2 * hDimY, 2 * hDimZ), hThickness); 105 | } 106 | 107 | // ----------------------------------------------------------------------------- 108 | // Create the falling ball at the specified height, with specified vertical 109 | // initial velocity. 110 | // ----------------------------------------------------------------------------- 111 | std::shared_ptr CreateFallingBall(ChSystemMulticore* system) { 112 | // Create a contact material for the falling ball 113 | auto material_b = chrono_types::make_shared(); 114 | material_b->SetFriction(mu_b); 115 | 116 | // Create the falling ball body 117 | auto ball = chrono_types::make_shared(); 118 | 119 | ball->SetMass(mass_b); 120 | ball->SetInertiaXX(inertia_b); 121 | ball->SetPos(ChVector3d(0, 0, initial_height)); 122 | ball->SetRot(ChQuaternion<>(1, 0, 0, 0)); 123 | ball->SetLinVel(ChVector3d(0, 0, initial_velocity)); 124 | ball->EnableCollision(true); 125 | ball->SetFixed(false); 126 | 127 | // Specify spherical contact and visualization shapes 128 | utils::AddSphereGeometry(ball.get(), material_b, R_b); 129 | 130 | system->AddBody(ball); 131 | 132 | return ball; 133 | } 134 | 135 | // ----------------------------------------------------------------------------- 136 | // Create the granular material, consisting of identical spheres with given 137 | // radius and material properties; the spheres are generated in a prismatic 138 | // region inside the container, using Poisson Disk sampling (thus ensuring that 139 | // no two spheres are closer than twice the radius) 140 | // ----------------------------------------------------------------------------- 141 | void CreateObjects(ChSystemMulticore* system) { 142 | // Create a contact material for granular bodies 143 | auto material_g = chrono_types::make_shared(); 144 | material_g->SetFriction(mu_g); 145 | 146 | //// ******************************************************************************** 147 | //// EXERCISE: 148 | //// Create a granular material generator with a mixture entirely made out of spheres 149 | //// of equal radius, all sharing the same contact material 150 | //// ******************************************************************************** 151 | utils::ChPDSampler sampler(2.01 * r_g); 152 | utils::ChGenerator gen(system); 153 | 154 | std::shared_ptr m1 = gen.AddMixtureIngredient(utils::MixtureType::SPHERE, 1.0); 155 | m1->SetDefaultMaterial(material_g); 156 | m1->SetDefaultDensity(rho_g); 157 | m1->SetDefaultSize(r_g); 158 | 159 | gen.SetStartTag(tag_particles); 160 | 161 | // Generate the granular bodies in a box within the container, using Poisson disk sampling 162 | gen.CreateObjectsBox(sampler, ChVector3d(0, 0, hDimZ / 2), ChVector3d(hDimX - r_g, hDimY - r_g, hDimZ / 2 - r_g)); 163 | 164 | std::cout << "Generated " << gen.GetTotalNumBodies() << " bodies" << std::endl; 165 | } 166 | 167 | // ----------------------------------------------------------------------------- 168 | int main(int argc, char* argv[]) { 169 | // Set the path to the Chrono data folder. 170 | SetChronoDataPath(CHRONO_DATA_DIR); 171 | 172 | // Create the (multicore) system and set method-specific solver settings. 173 | ChSystemMulticore* system = new ChSystemMulticoreNSC; 174 | 175 | system->SetCollisionSystemType(ChCollisionSystem::Type::MULTICORE); 176 | 177 | system->GetSettings()->solver.solver_type = SolverType::BB; 178 | system->GetSettings()->solver.solver_mode = SolverMode::SLIDING; 179 | system->GetSettings()->solver.max_iteration_normal = 0; 180 | system->GetSettings()->solver.max_iteration_sliding = 100; 181 | system->GetSettings()->solver.max_iteration_spinning = 0; 182 | system->GetSettings()->solver.alpha = 0; 183 | system->GetSettings()->solver.contact_recovery_speed = 0.1; 184 | 185 | double time_step = 1e-3; 186 | 187 | // Set number of threads. 188 | int max_threads = omp_get_num_procs(); 189 | if (threads > max_threads) 190 | threads = max_threads; 191 | omp_set_num_threads(threads); 192 | std::cout << "Using " << threads << " threads" << std::endl; 193 | 194 | // Set gravitational acceleration 195 | system->SetGravitationalAcceleration(ChVector3d(0, 0, -9.81)); 196 | 197 | // Edit system settings 198 | system->GetSettings()->solver.use_full_inertia_tensor = false; 199 | system->GetSettings()->solver.tolerance = 1.0; 200 | 201 | system->GetSettings()->collision.narrowphase_algorithm = ChNarrowphase::Algorithm::HYBRID; 202 | system->GetSettings()->collision.collision_envelope = 0.05 * r_g; 203 | 204 | //// ****************************************************** 205 | //// EXERCISE: 206 | //// Provide a more efficient split of bins for broad-phase 207 | //// ****************************************************** 208 | system->GetSettings()->collision.bins_per_axis = vec3(20, 20, 10); 209 | 210 | // Create the objects 211 | CreateContainer(system); 212 | auto ball = CreateFallingBall(system); 213 | CreateObjects(system); 214 | 215 | // Simulation loop 216 | 217 | #ifdef CHRONO_VSG 218 | auto vis = chrono_types::make_shared(); 219 | vis->AttachSystem(system); 220 | vis->SetWindowTitle("Crater Test"); 221 | vis->SetWindowSize(1280, 720); 222 | vis->SetCameraVertical(CameraVerticalDir::Z); 223 | vis->AddCamera(ChVector3d(0, -7 * hDimY, hDimZ), ChVector3d(0, 0, hDimZ)); 224 | vis->SetCameraAngleDeg(40.0); 225 | vis->SetBackgroundColor(ChColor(0.8f, 0.85f, 0.9f)); 226 | vis->EnableSkyBox(); 227 | vis->SetLightIntensity(1.0f); 228 | vis->SetLightDirection(1.5 * CH_PI_2, CH_PI_4); 229 | vis->EnableShadows(); 230 | vis->Initialize(); 231 | #endif 232 | 233 | double out_fps = 120; 234 | 235 | double time_end = 5; 236 | double time = 0; 237 | int sim_frame = 0; 238 | int out_frame = 0; 239 | double exec_time = 0; 240 | int num_contacts = 0; 241 | 242 | while (time < time_end) { 243 | if (time >= out_frame / out_fps) { 244 | cout << endl; 245 | cout << "---- Frame: " << out_frame << endl; 246 | cout << " Sim frame: " << sim_frame << endl; 247 | cout << " Time: " << time << endl; 248 | cout << " Num. contacts: " << num_contacts << endl; 249 | 250 | out_frame++; 251 | num_contacts = 0; 252 | } 253 | 254 | // Advance simulation by one step 255 | #ifdef CHRONO_VSG 256 | if (vis->Run()) { 257 | system->DoStepDynamics(time_step); 258 | vis->Render(); 259 | } else 260 | break; 261 | #else 262 | system->DoStepDynamics(time_step); 263 | #endif 264 | 265 | time += time_step; 266 | sim_frame++; 267 | num_contacts += system->GetNumContacts(); 268 | } 269 | 270 | delete system; 271 | return 0; 272 | } 273 | -------------------------------------------------------------------------------- /Chrono/multicore/cratering_solution_2.cpp: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // PROJECT CHRONO - http://projectchrono.org 3 | // 4 | // Copyright (c) 2014 projectchrono.org 5 | // All right reserved. 6 | // 7 | // Use of this source code is governed by a BSD-style license that can be found 8 | // in the LICENSE file at the top level of the distribution and at 9 | // http://projectchrono.org/license-chrono.txt. 10 | // 11 | // ============================================================================= 12 | // Author: Radu Serban 13 | // ============================================================================= 14 | // 15 | // Chrono::Multicore tutorial. 16 | // 17 | // The model simulated here consists of a spherical projectile dropped in a 18 | // bed of granular material, using either penalty or complementarity method for 19 | // frictional contact. 20 | // 21 | // SOLUTION for EXERCISE 2: 22 | // - use PENALTY-based contact and friction method 23 | // - replace Chrono::Multicore system type 24 | // - use appropriate contact material type and settings 25 | // 26 | // The global reference frame has Z up. 27 | // All units SI. 28 | // ============================================================================= 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include "chrono/ChConfig.h" 35 | #include "chrono/utils/ChUtilsCreators.h" 36 | #include "chrono/utils/ChUtilsGenerators.h" 37 | 38 | #include "chrono_multicore/physics/ChSystemMulticore.h" 39 | 40 | #ifdef CHRONO_VSG 41 | #include "chrono_vsg/ChVisualSystemVSG.h" 42 | using namespace chrono::vsg3d; 43 | #endif 44 | 45 | using namespace chrono; 46 | 47 | using std::cout; 48 | using std::endl; 49 | using std::flush; 50 | 51 | // ----------------------------------------------------------------------------- 52 | // Problem definitions 53 | // ----------------------------------------------------------------------------- 54 | 55 | // Desired number of OpenMP threads (will be clamped to maximum available) 56 | int threads = 4; 57 | 58 | // Parameters for the granular material 59 | int tag_particles = 0; // all particles wilkl have tag at least this value 60 | double r_g = 2e-3; 61 | double rho_g = 2500; 62 | double vol_g = (4.0 / 3) * CH_PI * r_g * r_g * r_g; 63 | double mass_g = rho_g * vol_g; 64 | ChVector3d inertia_g = 0.4 * mass_g * r_g * r_g * ChVector3d(1, 1, 1); 65 | 66 | float Y_g = 1e7f; 67 | float mu_g = 0.3f; 68 | float cr_g = 0.1f; 69 | 70 | // Parameters for the falling ball 71 | double R_b = 1.5e-2; 72 | double rho_b = 700; 73 | double vol_b = (4.0 / 3) * CH_PI * R_b * R_b * R_b; 74 | double mass_b = rho_b * vol_b; 75 | ChVector3d inertia_b = 0.4 * mass_b * R_b * R_b * ChVector3d(1, 1, 1); 76 | 77 | float Y_b = 1e8f; 78 | float mu_b = 0.3f; 79 | float cr_b = 0.1f; 80 | 81 | // Parameters for the containing bin 82 | double hDimX = 4e-2; // length in x direction 83 | double hDimY = 4e-2; // depth in y direction 84 | double hDimZ = 4e-2; // height in z direction 85 | double hThickness = 0.5e-2; // wall thickness 86 | 87 | float Y_c = 2e6f; 88 | float mu_c = 0.3f; 89 | float cr_c = 0.1f; 90 | 91 | // Drop height and vertical velocity 92 | double initial_height = 0.1; 93 | double initial_velocity = 0; 94 | 95 | // ----------------------------------------------------------------------------- 96 | // Create the container (five boxes) 97 | // ----------------------------------------------------------------------------- 98 | void CreateContainer(ChSystemMulticore* system) { 99 | // Create a material for the container 100 | auto material_c = chrono_types::make_shared(); 101 | material_c->SetYoungModulus(Y_c); 102 | material_c->SetFriction(mu_c); 103 | material_c->SetRestitution(cr_c); 104 | 105 | // Create the container. This utility function creates the container body (fixed to "ground") 106 | // and sets both the contact and visualization shapes. 107 | utils::CreateBoxContainer(system, material_c, ChVector3d(2 * hDimX, 2 * hDimY, 2 * hDimZ), hThickness); 108 | } 109 | 110 | // ----------------------------------------------------------------------------- 111 | // Create the falling ball at the specified height, with specified vertical 112 | // initial velocity. 113 | // ----------------------------------------------------------------------------- 114 | std::shared_ptr CreateFallingBall(ChSystemMulticore* system) { 115 | // Create a contact material for the falling ball 116 | auto material_b = chrono_types::make_shared(); 117 | material_b->SetYoungModulus(Y_b); 118 | material_b->SetFriction(mu_b); 119 | material_b->SetRestitution(cr_b); 120 | 121 | // Create the falling ball body 122 | auto ball = chrono_types::make_shared(); 123 | 124 | ball->SetMass(mass_b); 125 | ball->SetInertiaXX(inertia_b); 126 | ball->SetPos(ChVector3d(0, 0, initial_height)); 127 | ball->SetRot(ChQuaternion<>(1, 0, 0, 0)); 128 | ball->SetLinVel(ChVector3d(0, 0, initial_velocity)); 129 | ball->EnableCollision(true); 130 | ball->SetFixed(false); 131 | 132 | // Specify spherical contact and visualization shapes 133 | utils::AddSphereGeometry(ball.get(), material_b, R_b); 134 | 135 | system->AddBody(ball); 136 | 137 | return ball; 138 | } 139 | 140 | // ----------------------------------------------------------------------------- 141 | // Create the granular material, consisting of identical spheres with given 142 | // radius and material properties; the spheres are generated in a prismatic 143 | // region inside the container, using Poisson Disk sampling (thus ensuring that 144 | // no two spheres are closer than twice the radius) 145 | // ----------------------------------------------------------------------------- 146 | void CreateObjects(ChSystemMulticore* system) { 147 | // Create a contact material for granular bodies 148 | auto material_g = chrono_types::make_shared(); 149 | material_g->SetYoungModulus(Y_g); 150 | material_g->SetFriction(mu_g); 151 | material_g->SetRestitution(cr_g); 152 | 153 | //// ******************************************************************************** 154 | //// EXERCISE: 155 | //// Create a granular material generator with a mixture entirely made out of spheres 156 | //// of equal radius, all sharing the same contact material 157 | //// ******************************************************************************** 158 | utils::ChPDSampler sampler(2.01 * r_g); 159 | utils::ChGenerator gen(system); 160 | 161 | std::shared_ptr m1 = gen.AddMixtureIngredient(utils::MixtureType::SPHERE, 1.0); 162 | m1->SetDefaultMaterial(material_g); 163 | m1->SetDefaultDensity(rho_g); 164 | m1->SetDefaultSize(r_g); 165 | 166 | gen.SetStartTag(tag_particles); 167 | 168 | // Generate the granular bodies in a box within the container, using Poisson disk sampling 169 | gen.CreateObjectsBox(sampler, ChVector3d(0, 0, hDimZ / 2), ChVector3d(hDimX - r_g, hDimY - r_g, hDimZ / 2 - r_g)); 170 | 171 | std::cout << "Generated " << gen.GetTotalNumBodies() << " bodies" << std::endl; 172 | } 173 | 174 | // ----------------------------------------------------------------------------- 175 | int main(int argc, char* argv[]) { 176 | // Set the path to the Chrono data folder. 177 | SetChronoDataPath(CHRONO_DATA_DIR); 178 | 179 | // Create the (multicore) system and set method-specific solver settings. 180 | ChSystemMulticoreSMC* system = new ChSystemMulticoreSMC; 181 | 182 | system->SetCollisionSystemType(ChCollisionSystem::Type::MULTICORE); 183 | 184 | system->GetSettings()->solver.contact_force_model = ChSystemSMC::Hooke; 185 | system->GetSettings()->solver.tangential_displ_mode = ChSystemSMC::TangentialDisplacementModel::OneStep; 186 | system->GetSettings()->solver.use_material_properties = true; 187 | 188 | double time_step = 1e-4; 189 | 190 | // Set number of threads. 191 | int max_threads = omp_get_num_procs(); 192 | if (threads > max_threads) 193 | threads = max_threads; 194 | omp_set_num_threads(threads); 195 | std::cout << "Using " << threads << " threads" << std::endl; 196 | 197 | // Set gravitational acceleration 198 | system->SetGravitationalAcceleration(ChVector3d(0, 0, -9.81)); 199 | 200 | // Edit system settings 201 | system->GetSettings()->solver.use_full_inertia_tensor = false; 202 | system->GetSettings()->solver.tolerance = 1.0; 203 | 204 | system->GetSettings()->collision.narrowphase_algorithm = ChNarrowphase::Algorithm::HYBRID; 205 | system->GetSettings()->collision.collision_envelope = 0.05 * r_g; 206 | 207 | //// ****************************************************** 208 | //// EXERCISE: 209 | //// Provide a more efficient split of bins for broad-phase 210 | //// ****************************************************** 211 | system->GetSettings()->collision.bins_per_axis = vec3(20, 20, 10); 212 | 213 | // Create the objects 214 | CreateContainer(system); 215 | auto ball = CreateFallingBall(system); 216 | CreateObjects(system); 217 | 218 | // Simulation loop 219 | 220 | #ifdef CHRONO_VSG 221 | auto vis = chrono_types::make_shared(); 222 | vis->AttachSystem(system); 223 | vis->SetWindowTitle("Crater Test"); 224 | vis->SetWindowSize(1280, 720); 225 | vis->SetCameraVertical(CameraVerticalDir::Z); 226 | vis->AddCamera(ChVector3d(0, -7 * hDimY, hDimZ), ChVector3d(0, 0, hDimZ)); 227 | vis->SetCameraAngleDeg(40.0); 228 | vis->SetBackgroundColor(ChColor(0.8f, 0.85f, 0.9f)); 229 | vis->EnableSkyBox(); 230 | vis->SetLightIntensity(1.0f); 231 | vis->SetLightDirection(1.5 * CH_PI_2, CH_PI_4); 232 | vis->EnableShadows(); 233 | vis->Initialize(); 234 | #endif 235 | 236 | double out_fps = 120; 237 | 238 | double time_end = 5; 239 | double time = 0; 240 | int sim_frame = 0; 241 | int out_frame = 0; 242 | double exec_time = 0; 243 | int num_contacts = 0; 244 | 245 | while (time < time_end) { 246 | if (time >= out_frame / out_fps) { 247 | cout << endl; 248 | cout << "---- Frame: " << out_frame << endl; 249 | cout << " Sim frame: " << sim_frame << endl; 250 | cout << " Time: " << time << endl; 251 | cout << " Num. contacts: " << num_contacts << endl; 252 | 253 | out_frame++; 254 | num_contacts = 0; 255 | } 256 | 257 | // Advance simulation by one step 258 | #ifdef CHRONO_VSG 259 | if (vis->Run()) { 260 | system->DoStepDynamics(time_step); 261 | vis->Render(); 262 | } else 263 | break; 264 | #else 265 | system->DoStepDynamics(time_step); 266 | #endif 267 | 268 | time += time_step; 269 | sim_frame++; 270 | num_contacts += system->GetNumContacts(); 271 | } 272 | 273 | delete system; 274 | return 0; 275 | } 276 | -------------------------------------------------------------------------------- /Chrono/slider_crank/slider_crank_1_solution.cpp: -------------------------------------------------------------------------------- 1 | // ============================================================================= 2 | // PROJECT CHRONO - http://projectchrono.org 3 | // 4 | // Copyright (c) 2014 projectchrono.org 5 | // All right reserved. 6 | // 7 | // Use of this source code is governed by a BSD-style license that can be found 8 | // in the LICENSE file at the top level of the distribution and at 9 | // http://projectchrono.org/license-chrono.txt. 10 | // 11 | // ============================================================================= 12 | // Author: Radu Serban 13 | // ============================================================================= 14 | // 15 | // Slider-crank Chrono tutorial (model 1) 16 | // 17 | // This model is a 3-body slider-crank consisting of crank, slider and connecting 18 | // rod bodies. The crank is connected to ground with a revolute joint and the 19 | // slider is connected to ground through a prismatic joint. The connecting rod 20 | // connects to the crank through a spherical joint and to the slider through a 21 | // universal joint. 22 | // 23 | // The crank body is driven at constant angular speed, under the action of gravity, 24 | // acting in the negative Z direction. 25 | // 26 | // The simulation is animated with Irrlicht. 27 | // 28 | // ============================================================================= 29 | 30 | #include 31 | #include 32 | 33 | #include "chrono/physics/ChLinkMotorRotationSpeed.h" 34 | #include "chrono/physics/ChSystemNSC.h" 35 | #include "chrono/core/ChRealtimeStep.h" 36 | #include "chrono_irrlicht/ChVisualSystemIrrlicht.h" 37 | 38 | using namespace chrono; 39 | using namespace chrono::irrlicht; 40 | using namespace irr; 41 | 42 | int main(int argc, char* argv[]) { 43 | // 0. Set the path to the Chrono data folder 44 | 45 | SetChronoDataPath(CHRONO_DATA_DIR); 46 | 47 | // 1. Create the physical system that will handle all bodies and constraints. 48 | 49 | // Specify the gravitational acceleration vector, consistent with the 50 | // global reference frame having Z up. 51 | ChSystemNSC system; 52 | system.SetGravitationalAcceleration(ChVector3d(0, 0, -9.81)); 53 | 54 | // 2. Create the rigid bodies of the slider-crank mechanical system. 55 | // For each body, specify: 56 | // - a unique identifier 57 | // - mass and moments of inertia 58 | // - position and orientation of the (centroidal) body frame 59 | // - visualization assets (defined with respect to the body frame) 60 | 61 | // Ground 62 | auto ground = chrono_types::make_shared(); 63 | system.AddBody(ground); 64 | ground->SetName("ground"); 65 | ground->SetFixed(true); 66 | 67 | auto cyl_g = chrono_types::make_shared(0.03, 0.4); 68 | ground->AddVisualShape(cyl_g, ChFrame<>(VNULL, QuatFromAngleX(CH_PI_2))); 69 | 70 | // Crank 71 | auto crank = chrono_types::make_shared(); 72 | system.AddBody(crank); 73 | crank->SetName("crank"); 74 | crank->SetMass(1.0); 75 | crank->SetInertiaXX(ChVector3d(0.005, 0.1, 0.1)); 76 | crank->SetPos(ChVector3d(-1, 0, 0)); 77 | crank->SetRot(ChQuaternion<>(1, 0, 0, 0)); 78 | 79 | auto box_c = chrono_types::make_shared(1.9, 0.1, 0.1); 80 | box_c->SetColor(ChColor(0.6f, 0.2f, 0.2f)); 81 | crank->AddVisualShape(box_c); 82 | 83 | auto cyl_c = chrono_types::make_shared(0.05, 0.2); 84 | cyl_c->SetColor(ChColor(0.6f, 0.2f, 0.2f)); 85 | crank->AddVisualShape(cyl_c, ChFrame<>(ChVector3d(1, 0, 0), QuatFromAngleX(CH_PI_2))); 86 | 87 | auto sph_c = chrono_types::make_shared(0.05); 88 | sph_c->SetColor(ChColor(0.6f, 0.2f, 0.2f)); 89 | crank->AddVisualShape(sph_c, ChFrame<>(ChVector3d(-1, 0, 0))); 90 | 91 | // Slider 92 | auto slider = chrono_types::make_shared(); 93 | system.AddBody(slider); 94 | slider->SetName("slider"); 95 | slider->SetMass(1.0); 96 | slider->SetInertiaXX(ChVector3d(0.05, 0.05, 0.05)); 97 | slider->SetPos(ChVector3d(2, 0, 0)); 98 | slider->SetRot(ChQuaternion<>(1, 0, 0, 0)); 99 | 100 | auto box_s = chrono_types::make_shared(0.4, 0.2, 0.2); 101 | box_s->SetColor(ChColor(0.2f, 0.2f, 0.6f)); 102 | slider->AddVisualShape(box_s); 103 | 104 | auto cyl_s = chrono_types::make_shared(0.03, 0.4); 105 | cyl_s->SetColor(ChColor(0.2f, 0.2f, 0.6f)); 106 | slider->AddVisualShape(cyl_s, ChFrame<>(VNULL, QuatFromAngleX(CH_PI_2))); 107 | 108 | //// ------------------------------------------------------------------------- 109 | //// EXERCISE 1.1 110 | //// Create a connecting rod body to replace the distance constraint. 111 | //// This body should have: 112 | //// mass: 0.5 113 | //// moments of inertia: I_xx = 0.005, I_yy = 0.1, I_zz = 0.1 114 | //// visualization: a green box with width and height 0.1 115 | //// ------------------------------------------------------------------------- 116 | 117 | // Connecting rod 118 | auto rod = chrono_types::make_shared(); 119 | system.AddBody(rod); 120 | rod->SetName("rod"); 121 | rod->SetMass(0.5); 122 | rod->SetInertiaXX(ChVector3d(0.005, 0.1, 0.1)); 123 | rod->SetPos(ChVector3d(0, 0, 0)); 124 | rod->SetRot(ChQuaternion<>(1, 0, 0, 0)); 125 | 126 | auto box_r = chrono_types::make_shared(4, 0.1, 0.1); 127 | box_r->SetColor(ChColor(0.2f, 0.6f, 0.2f)); 128 | rod->AddVisualShape(box_r); 129 | 130 | auto cyl_r = chrono_types::make_shared(0.03, 0.4); 131 | cyl_r->SetColor(ChColor(0.2f, 0.6f, 0.2f)); 132 | rod->AddVisualShape(cyl_r, ChFrame<>(ChVector3d(2, 0, 0), QuatFromAngleX(CH_PI_2))); 133 | 134 | // 3. Create joint constraints. 135 | // All joint frames are specified in the global frame. 136 | 137 | // Define two quaternions representing: 138 | // - a rotation of -90 degrees around x (z2y) 139 | // - a rotation of +90 degrees around y (z2x) 140 | ChQuaternion<> z2y; 141 | ChQuaternion<> z2x; 142 | z2y.SetFromAngleAxis(-CH_PI / 2, ChVector3d(1, 0, 0)); 143 | z2x.SetFromAngleAxis(CH_PI / 2, ChVector3d(0, 1, 0)); 144 | 145 | //// ------------------------------------------------------------------------- 146 | //// EXERCISE 1.2 147 | //// Replace the revolute joint between ground and crank with a 148 | //// ChLinkMotorRotationSpeed element and enforce constant angular speed of 149 | //// 90 degrees/s. 150 | //// ------------------------------------------------------------------------- 151 | 152 | // Create a ChFunction object that always returns the constant value PI/2. 153 | auto fun = chrono_types::make_shared(); 154 | fun->SetConstant(CH_PI); 155 | 156 | // Motor between ground and crank. 157 | // Note that this also acts as a revolute joint (i.e. it enforces the same 158 | // kinematic constraints as a revolute joint). As before, we apply the 'z2y' 159 | // rotation to align the rotation axis with the Y axis of the global frame. 160 | auto engine_ground_crank = chrono_types::make_shared(); 161 | engine_ground_crank->SetName("engine_ground_crank"); 162 | engine_ground_crank->Initialize(ground, crank, ChFrame<>(ChVector3d(0, 0, 0), z2y)); 163 | engine_ground_crank->SetSpeedFunction(fun); 164 | system.AddLink(engine_ground_crank); 165 | 166 | // Prismatic joint between ground and slider. 167 | // The translational axis of a prismatic joint is along the Z axis of the 168 | // specified joint coordinate system. Here, we apply the 'z2x' rotation to 169 | // align it with the X axis of the global reference frame. 170 | auto prismatic_ground_slider = chrono_types::make_shared(); 171 | prismatic_ground_slider->SetName("prismatic_ground_slider"); 172 | prismatic_ground_slider->Initialize(ground, slider, ChFrame<>(ChVector3d(2, 0, 0), z2x)); 173 | system.AddLink(prismatic_ground_slider); 174 | 175 | //// ------------------------------------------------------------------------- 176 | //// EXERCISE 1.3 177 | //// Replace the distance constraint with joints connecting the rod to the 178 | //// crank (use ChLinkLockSpherical) and to the slider (ChLinkUniversal). The 179 | //// universal joint's cross should be aligned with the Z and Y global axes. 180 | //// ------------------------------------------------------------------------- 181 | 182 | // Spherical joint between crank and rod 183 | auto spherical_crank_rod = chrono_types::make_shared(); 184 | spherical_crank_rod->SetName("spherical_crank_rod"); 185 | spherical_crank_rod->Initialize(crank, rod, ChFrame<>(ChVector3d(-2, 0, 0), QUNIT)); 186 | system.AddLink(spherical_crank_rod); 187 | 188 | // Universal joint between rod and slider. 189 | // The "cross" of a universal joint is defined using the X and Y axes of the 190 | // specified joint coordinate frame. Here, we apply the 'z2x' rotation so that 191 | // the cross is aligned with the Z and Y axes of the global reference frame. 192 | auto universal_rod_slider = chrono_types::make_shared(); 193 | universal_rod_slider->SetName("universal_rod_slider"); 194 | universal_rod_slider->Initialize(rod, slider, ChFrame<>(ChVector3d(2, 0, 0), z2x)); 195 | system.AddLink(universal_rod_slider); 196 | 197 | // 4. Write the system hierarchy to the console (default log output destination) 198 | system.ShowHierarchy(std::cout); 199 | 200 | // 5. Prepare visualization with Irrlicht 201 | // Note that Irrlicht uses left-handed frames with Y up. 202 | 203 | // Create the Irrlicht application and set-up the camera. 204 | auto vis = chrono_types::make_shared(); 205 | vis->SetWindowSize(800, 600); 206 | vis->SetCameraVertical(CameraVerticalDir::Z); 207 | vis->SetWindowTitle("Slider-Crank Demo 1"); 208 | vis->Initialize(); 209 | vis->AddLogo(); 210 | vis->AddSkyBox(); 211 | vis->AddCamera(ChVector3d(2, -5, 0), ChVector3d(2, 0, 0)); 212 | vis->AddTypicalLights(); 213 | vis->AttachSystem(&system); 214 | 215 | // 6. Perform the simulation. 216 | 217 | ChRealtimeStepTimer realtime_timer; 218 | while (vis->Run()) { 219 | // Initialize the graphical scene. 220 | vis->BeginScene(); 221 | 222 | // Render all visualization objects. 223 | vis->Render(); 224 | 225 | // Draw an XZ grid at the global origin to add in visualization. 226 | tools::drawGrid(vis.get(), 1, 1, 20, 20, ChCoordsys<>(ChVector3d(0.01, 0, 0.01), QuatFromAngleX(CH_PI_2)), 227 | ChColor(0.6f, 0.6f, 0.6f), true); 228 | tools::drawAllCOGs(vis.get(), 1.0); 229 | 230 | // Finalize the graphical scene. 231 | vis->EndScene(); 232 | 233 | // Advance simulation by one step. 234 | system.DoStepDynamics(0.01); 235 | realtime_timer.Spin(0.01); 236 | } 237 | 238 | return 0; 239 | } 240 | --------------------------------------------------------------------------------