Commit a07790b0 authored by Alexander Kreibich's avatar Alexander Kreibich

Your commit message

parent 04fb3a44
......@@ -34,6 +34,7 @@ public class CollisionTestPerformer : MonoBehaviour
*/
private void PerformCollisionTests()
{
if (doCollisionTestOne) PerformCollisionTestOne();
else if (doCollisionTestTwo) StartCoroutine(PerformCollisionTestTwo());
else if (doCollisionTestThree) StartCoroutine(PerformCollisionTestThree());
......@@ -54,7 +55,7 @@ public class CollisionTestPerformer : MonoBehaviour
}
// force gets applied for a fixed time
private IEnumerator PerformCollisionTestTwo(float applyForceTime = 1.5f)
private IEnumerator PerformCollisionTestTwo(float applyForceTime = 0.0000001f)
{
for (int sphereIndex = 0; sphereIndex < (simulationLoop.SpheresCount - 1); sphereIndex++)
{
......@@ -74,7 +75,7 @@ public class CollisionTestPerformer : MonoBehaviour
}
// force gets applied until a fixed velocity is reached
private IEnumerator PerformCollisionTestThree(float exitVelocity = 4f)
private IEnumerator PerformCollisionTestThree(float exitVelocity = 40f)
{
for (int sphereIndex = 0; sphereIndex < (simulationLoop.SpheresCount - 1); sphereIndex++)
{
......@@ -95,7 +96,7 @@ public class CollisionTestPerformer : MonoBehaviour
}
// force gets applied for the whole time
private IEnumerator PerformCollisionTestFour(float pullForceFactor = 0.3f)
private IEnumerator PerformCollisionTestFour(float pullForceFactor = 1f)
{
float appliedPullForce = pullForceFactor * pullForce.z;
......@@ -107,9 +108,10 @@ public class CollisionTestPerformer : MonoBehaviour
simulationLoop.sphereExternalForces[sphereIndex] = Vector3.zero;
}
simulationLoop.sphereExternalForces[simulationLoop.SpheresCount - 1] = pullForceFactor * pullForce;
simulationLoop.sphereExternalForces[0] = pullForceFactor * pullForce;
yield return null;
}
}
}
}
......@@ -3,6 +3,7 @@ using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
using BSM = BulletSharp.Math;
using System.IO;
namespace GuidewireSim
{
......@@ -18,8 +19,14 @@ public class ConstraintSolvingStep : MonoBehaviour
BSM.Quaternion deltaOrientation = new BSM.Quaternion(); //!< The correction of @p orientation in method SolveStretchConstraint().
BSM.Quaternion deltaOrientationOne = new BSM.Quaternion(); //!< The correction of @p orientationOne in method SolveBendTwistConstraint().
BSM.Quaternion deltaOrientationTwo = new BSM.Quaternion(); //!< The correction of @p orientationTwo in method SolveBendTwistConstraint().
private List<Vector3> allDeltaPositionOnes = new List<Vector3>();
private List<Vector3> allDeltaPositionTwos = new List<Vector3>();
private List<BSM.Quaternion> allDeltaOrientations = new List<BSM.Quaternion>();
private List<BSM.Quaternion> allDeltaOrientationOnes = new List<BSM.Quaternion>();
private List<BSM.Quaternion> allDeltaOrientationTwos = new List<BSM.Quaternion>();
float stretchStiffness = 0.1f;
float stretchStiffness = 0.1f;
float bendStiffness = 0.1f;
[Tooltip("Whether to solve both constraints in bilateral interleaving order. Naive order is used when false.")]
......@@ -281,8 +288,8 @@ public class ConstraintSolvingStep : MonoBehaviour
*/
public void SolveStretchConstraint(Vector3 particlePositionOne, Vector3 particlePositionTwo, BSM.Quaternion orientation,
BSM.Quaternion e_3, float rodElementLength, out Vector3 deltaPositionOne,
out Vector3 deltaPositionTwo, out BSM.Quaternion deltaOrientation, float inverseMassOne = 1f,
float inverseMassTwo = 1f, float inertiaWeight = 1f)
out Vector3 deltaPositionTwo, out BSM.Quaternion deltaOrientation, float inverseMassOne = 1000f,
float inverseMassTwo = 1000f, float inertiaWeight = 1f)
{
Assert.AreApproximatelyEqual(1f, mathHelper.QuaternionLength(orientation), tolerance: 0.01f);
Assert.AreApproximatelyEqual(1f, mathHelper.QuaternionLength(e_3), tolerance: 0.01f);
......@@ -351,19 +358,28 @@ public class ConstraintSolvingStep : MonoBehaviour
* @req The relevant entries of @p cylinderOrientationPredictions should be unit quaternions, i.e. have length approximately equal to one.
* @req After the quaternion prediction got corrected, it should again be a unit quaternions, i.e. have length approximately equal to one.
*/
private void CorrectStretchPredictions(int sphereIndex, Vector3[] spherePositionPredictions, BSM.Quaternion[] cylinderOrientationPredictions)
private void CorrectStretchPredictions(int sphereIndex, Vector3[] spherePositionPredictions, BSM.Quaternion[] cylinderOrientationPredictions)
{
Assert.IsTrue(sphereIndex >= 0);
Assert.AreApproximatelyEqual(1f, mathHelper.QuaternionLength(cylinderOrientationPredictions[sphereIndex]), tolerance: 0.01f);
string path = "/home/akreibich/TestRobinCode37/LogConstraints.txt";
using (StreamWriter writer = new StreamWriter(path, true)) // true to append data to the file
{
Assert.IsTrue(sphereIndex >= 0);
Assert.AreApproximatelyEqual(1f, mathHelper.QuaternionLength(cylinderOrientationPredictions[sphereIndex]), tolerance: 0.01f);
// Log the deltaPositionOne and deltaPositionTwo to the file
writer.WriteLine($"Delta Position One: {deltaPositionOne}");
writer.WriteLine($"Delta Position Two: {deltaPositionTwo}");
}
spherePositionPredictions[sphereIndex] += stretchStiffness * deltaPositionOne;
spherePositionPredictions[sphereIndex + 1] += stretchStiffness * deltaPositionTwo;
cylinderOrientationPredictions[sphereIndex] += stretchStiffness * deltaOrientation;
spherePositionPredictions[sphereIndex] += stretchStiffness * deltaPositionOne;
spherePositionPredictions[sphereIndex + 1] += stretchStiffness * deltaPositionTwo;
cylinderOrientationPredictions[sphereIndex] += stretchStiffness * deltaOrientation;
cylinderOrientationPredictions[sphereIndex].Normalize();
cylinderOrientationPredictions[sphereIndex].Normalize();
Assert.AreApproximatelyEqual(1f, mathHelper.QuaternionLength(cylinderOrientationPredictions[sphereIndex]), tolerance: 0.01f);
}
Assert.AreApproximatelyEqual(1f, mathHelper.QuaternionLength(cylinderOrientationPredictions[sphereIndex]), tolerance: 0.01f);
}
/**
* Corrects the predictions of the bend twist constraint by adding @p deltaOrientationOne and @p deltaOrientationTwo.
......@@ -387,6 +403,13 @@ public class ConstraintSolvingStep : MonoBehaviour
Assert.AreApproximatelyEqual(1f, mathHelper.QuaternionLength(cylinderOrientationPredictions[cylinderIndex]), tolerance: 0.01f);
Assert.AreApproximatelyEqual(1f, mathHelper.QuaternionLength(cylinderOrientationPredictions[cylinderIndex + 1]), tolerance: 0.01f);
allDeltaOrientationOnes.Add(deltaOrientationOne);
allDeltaOrientationTwos.Add(deltaOrientationTwo);
}
public List<Vector3> GetAllDeltaPositionOnes() => allDeltaPositionOnes;
public List<Vector3> GetAllDeltaPositionTwos() => allDeltaPositionTwos;
public List<BSM.Quaternion> GetAllDeltaOrientations() => allDeltaOrientations;
public List<BSM.Quaternion> GetAllDeltaOrientationOnes() => allDeltaOrientationOnes;
public List<BSM.Quaternion> GetAllDeltaOrientationTwos() => allDeltaOrientationTwos;
}
}
}
\ No newline at end of file
......@@ -4,35 +4,48 @@ using GuidewireSim;
public class CreationScript : MonoBehaviour
{
public GameObject spherePrefab;
public GameObject cylinderPrefab;
private int spheresCount;
private int cylinderCount;
private GameObject[] spheres;
private GameObject[] cylinders;
private string logFilePath = "";
public GameObject spherePrefab; //This is for choosing a Prefab for the sphere element. One can directly gain this in Robins code from: Assets/Guidewire_Assets/Prefabs
public GameObject cylinderPrefab; //This is for choosing a Prefab for the cylinder element. One can directly gain this in Robins code from: Assets/Guidewire_Assets/Prefabs
private int spheresCount; //This variable is used to store the number of spheres in the guidewire, so the script can keep knowledge on how many spheres were created
private GameObject[] spheres; //This array is used to store references to the sphere game objects in the guidewire. //This array is used to store references to the sphere game objects in the guidewire.
private GameObject[] cylinders; //-''-
private SimulationLoop simulationLoop;
void Start()
{
simulationLoop = GameObject.Find("Simulation").GetComponent<SimulationLoop>();
InvokeRepeating("SavePositionsToFile", 0f, 1f);
}
void FixedUpdate()
private void Awake()
{
SavePositionsToFile();
string[] args = System.Environment.GetCommandLineArgs();
for (int i = 0; i < args.Length; i++)
{
if (args[i] == "-logFilePath" && args.Length > i + 1)
{
logFilePath = args[i + 1];
}
}
}
void FixedUpdate()
{
//SavePositionsToFile();
}
//This code segment is responsible for creating and positioning the spheres and cylinders
public void CreateGuidewire(int numberElements)
{
spheres = new GameObject[numberElements];
cylinders = new GameObject[numberElements - 1];
//Here we use GetComponent to recieve the value of the variable rodElementLength that is stored in the SimulationLoop script. As this variable needs to be private, we use a getter Method and therefore also call this instead of calling the variable directly.
float rEL = simulationLoop.GetRodElementLength();
for (int i = 0; i < numberElements; ++i)
{
GameObject sphere = Instantiate(spherePrefab);
sphere.transform.position = new Vector3(0, 7, -1000 + i * rEL);
sphere.transform.position = new Vector3(0, 0, -2000 + i * rEL);
sphere.transform.parent = this.transform;
spheres[i] = sphere;
......@@ -52,28 +65,25 @@ public class CreationScript : MonoBehaviour
simulationLoop.SetSpheres(spheres);
simulationLoop.SetCylinders(cylinders);
}
//Here I save the positions of the spheres to a .txt file. The file path has to be adapted to the local network for the file one wants to save the positons to
public void SavePositionsToFile()
{
string path = "/home/akreibich/TestRobinCode22/PositionTest22_2.txt";
StreamWriter writer = new StreamWriter(path, true);
if (spheresCount > 0)
{
Vector3 firstSpherePosition = spheres[0].transform.position;
writer.WriteLine("First Sphere: " + firstSpherePosition.x + "," + firstSpherePosition.y + "," + firstSpherePosition.z);
if (spheresCount > 1)
{
Vector3 lastSpherePosition = spheres[spheresCount - 1].transform.position;
writer.WriteLine("Last Sphere: " + lastSpherePosition.x + "," + lastSpherePosition.y + "," + lastSpherePosition.z);
}
}
writer.Close();
using (StreamWriter writer = new StreamWriter(logFilePath, true))
{
if (spheres != null && spheres.Length > 0)
{
Vector3 firstSpherePosition = spheres[0].transform.position;
writer.WriteLine("First Sphere: " + firstSpherePosition.x + "," + firstSpherePosition.y + "," + firstSpherePosition.z);
if (spheres.Length > 1)
{
Vector3 lastSpherePosition = spheres[spheres.Length - 1].transform.position;
writer.WriteLine("Last Sphere: " + lastSpherePosition.x + "," + lastSpherePosition.y + "," + lastSpherePosition.z);
}
}
}
}
public GameObject GetLastSphere()
......
......@@ -74,7 +74,7 @@ public class ForceTestPerformer : MonoBehaviour
*/
private void PerformForceTestTwo()
{
Vector3 pullForce = new Vector3(0f, 0.3f, 0f);
Vector3 pullForce = new Vector3(0f, 0f, 15f);
for (int sphereIndex = 0; sphereIndex < (simulationLoop.SpheresCount - 1); sphereIndex++)
{
......@@ -160,4 +160,4 @@ public class ForceTestPerformer : MonoBehaviour
+ Vector3.Distance(simulationLoop.spherePositions[0], simulationLoop.spherePositions[simulationLoop.SpheresCount - 1]));
}
}
}
\ No newline at end of file
}
......@@ -23,17 +23,18 @@ public class GuidewireCreateManager : MonoBehaviour
return; // Exit if SimulationLoop is not found
}
// Get the Rod Element Length
//again we need to get the rod element length from the simulation loop script;
REL = simulationLoop.GetRodElementLength();
int numberOfElements = (int)(L_0 / REL) + 1; // Calculate the desired number of elements
int numberOfElements = (int)(L_0 / REL) + 1;//This calculates the number of elements that now make up the discretized guidewire. The number of elements depends on the rod element length
// Find the CreationScript component in the scene
//now find the CreationScript component in the scene, to create the guidewire with the wanted number of elements and rod element length.
//This will cause the total length of the guidewire to stay the same
creationScript = FindObjectOfType<CreationScript>();
if (creationScript != null)
{
creationScript.CreateGuidewire(numberOfElements);
// Get the created spheres and cylinders from the CreationScript
//Get the created spheres and cylinders from the CreationScript
GameObject[] createdSpheres = creationScript.GetSpheres();
GameObject[] createdCylinders = creationScript.GetCylinders();
......
......@@ -17,7 +17,7 @@ namespace GuidewireSim
private MathHelper mathHelper;
[Range(1000f, 10000f)]
private float materialDensity = 7860;
private float materialDensity =7600;
[Range(0.0001f, 1f)]
private float materialRadius = 0.001f;
......@@ -65,14 +65,14 @@ namespace GuidewireSim
}
/**
* Initializes @p sphereInverseMasses with the default value of one at the start of the simulation.
* Initializes @p sphereInverseMasses with the default value of one at the start of the simulation. Edit: I (Alex Kreibich) adapt this so the total mass stays the same. The idea for how this works is described in my Bachelorthesis in the Methods Chapter
* @param spheresCount The count of all spheres of the guidewire. Equals the length of @p spherePositionPredictions.
* @param[out] sphereInverseMasses The constant inverse masses of each sphere.
*/
public void InitSphereInverseMasses(int spheresCount, out float[] sphereInverseMasses)
{
sphereInverseMasses = new float[spheresCount];
float inverseMassValue = ((2500/rodElementLength)+1)/2;
float inverseMassValue = ((2000/rodElementLength)+1)/50;
for (int sphereIndex = 0; sphereIndex < spheresCount; sphereIndex++)
{
......@@ -159,7 +159,7 @@ namespace GuidewireSim
for (int cylinderIndex = 0; cylinderIndex < cylinderCount; cylinderIndex++)
{
cylinderScalarWeights[cylinderIndex] = 1f;
cylinderScalarWeights[cylinderIndex] = 1f; //(50/(500/rodElementLength)-1);
}
}
......
......@@ -15,17 +15,17 @@ public class MeshImporter3 : MonoBehaviour
string[] args = Environment.GetCommandLineArgs();
File.AppendAllText(logFilePath, "Received arguments: " + string.Join(", ", args) + "\n");
string meshPath ="/home/akreibich/Desktop/Bachelor/Data (Binary)/Input/Input_MeshOption/DataForMeshes/Data10/Component1_normals1010_pos.obj";
string secondMeshPath = "/home/akreibich/Desktop/Bachelor/Data (Binary)/Input/Input_MeshOption/DataForMeshes/Data10/Component1_1010_pos.obj";
string meshPath ="";
string secondMeshPath = "";
//if run via the python loop, it should be like this
//Vector3 position = Vector3.zero;
//Vector3 scale = Vector3.one;
//Vector3 rotation = Vector3.zero;
Vector3 position = Vector3.zero;
Vector3 scale = Vector3.one;
Vector3 rotation = Vector3.zero;
//Change it to this for testing
Vector3 position = new Vector3(1311f, -392f, -1197f);
Vector3 scale = new Vector3(27.2f, 27.2f, 27.2f);
Vector3 rotation = new Vector3(0f, -86.6f, 0f);
//Vector3 position = new Vector3(1311f, -392f, -1197f);
//Vector3 scale = new Vector3(27.2f, 27.2f, 27.2f);
//Vector3 rotation = new Vector3(0f, -86.6f, 0f);
for (int i = 0; i < args.Length; i++)
{
......
......@@ -5,11 +5,18 @@ using UnityEngine;
using UnityEngine.Assertions;
using BSM = BulletSharp.Math;
using System.IO;
using System.Diagnostics;
using Debug = UnityEngine.Debug;
namespace GuidewireSim
{
public class SimulationLoop : MonoBehaviour
{
//public int count; //hier aus CreationScript
//CreationScript creationScript; //hier -""-
private Stopwatch stopwatch;
public Camera followingCamera; // Drag your camera here in the Unity Editor
private Vector3 cameraOffset = new Vector3(0, 781, 0); // The offset of the camera in the y direction is 781
private string logFilePath = "";
......@@ -81,7 +88,7 @@ namespace GuidewireSim
public float GetRodElementLength(){
return rodElementLength;
}
float rodElementLength = 100f;
float rodElementLength =10f;
......@@ -113,6 +120,15 @@ namespace GuidewireSim
private void Awake()
{
//GameObject creationObject = GameObject.Find("GameObjectCreationScript"); //hier aus creation script, alle 3 zeilen
//creationScript = creationObject.GetComponent<CreationScript>();
//int count = creationScript.spheresCount;
string[] args = System.Environment.GetCommandLineArgs();
for (int i = 0; i < args.Length; i++)
{
......@@ -129,7 +145,7 @@ namespace GuidewireSim
else
{
Debug.LogError("Failed to parse timeStep from command-line arguments. Using default value.");
timeStep = 0.02f;
timeStep = 0.01f;
}
}
}
......@@ -146,10 +162,11 @@ namespace GuidewireSim
else
{
Debug.LogError("Failed to parse rodElementLength from command-line arguments. Using default value.");
rodElementLength = 100f;
rodElementLength = 10f;
}
}
}
stopwatch = new Stopwatch();
Assert.IsFalse(spheres.Length == 0);
Assert.IsFalse(cylinders.Length == 0);
Assert.IsTrue(spheres.Length == cylinders.Length + 1);
......@@ -194,7 +211,7 @@ namespace GuidewireSim
Time.fixedDeltaTime = timeStep;
PerformInitializationStep();
InvokeRepeating("SavePositionsToFile", 1f, 1f);
//InvokeRepeating("SavePositionsToFile", 0f, 1f);
objectSetter.SetCylinderPositions(cylinders, CylinderCount, cylinderPositions);
objectSetter.SetCylinderOrientations(cylinders, CylinderCount, cylinderOrientations, directors);
......@@ -202,10 +219,26 @@ namespace GuidewireSim
private void FixedUpdate()
{
stopwatch.Restart();
if (ExecuteSingleLoopTest) return;
PerformSimulationLoop();
UpdateCameraPosition();
stopwatch.Stop();
long elapsedMilliseconds = stopwatch.ElapsedMilliseconds;
UnityEngine.Debug.Log($"FixedUpdate took {elapsedMilliseconds} ms");
string filePath = "/home/akreibich/TestRobinCode37/TimeCalculationsFixedUpdate.txt";
using (StreamWriter writer = new StreamWriter(filePath, true)) //The 'true" parameter appends to the file
{
writer.WriteLine($"FixedUpdate took {elapsedMilliseconds} ms");
}
string filePath2 = "/home/akreibich/TestRobinCode37/LogConstraints.txt";
using (StreamWriter writer = new StreamWriter(filePath2, true)) //same as above
{
writer.WriteLine($"FixedUpdate took place");
}
}
public void SavePositionsToFile()
......@@ -223,7 +256,7 @@ namespace GuidewireSim
{
if (spheres != null && spheres.Length > 0)
{
GameObject lastSphere = spheres[spheres.Length - 1];
GameObject lastSphere = spheres[0];
Vector3 newCameraPosition = lastSphere.transform.position + cameraOffset;
followingCamera.transform.position = newCameraPosition;
}
......@@ -263,7 +296,18 @@ namespace GuidewireSim
PerformPredictionStep();
AdaptCalculations();
SetCollidersStep();
}
if (solveStretchConstraints)
{
List<Vector3> allDeltaPositionOnes = constraintSolvingStep.GetAllDeltaPositionOnes();
List<Vector3> allDeltaPositionTwos = constraintSolvingStep.GetAllDeltaPositionTwos();
List<BSM.Quaternion> allDeltaOrientations = constraintSolvingStep.GetAllDeltaOrientations();
Debug.Log($"All Stretch Corrections - DeltaPositionOnes: {string.Join(", ", allDeltaPositionOnes)}, DeltaPositionTwos: {string.Join(", ", allDeltaPositionTwos)}, DeltaOrientations: {string.Join(", ", allDeltaOrientations)}");
}
}
private void PerformConstraintSolvingStep()
{
......@@ -281,6 +325,14 @@ namespace GuidewireSim
for (int solverStep = 0; solverStep < ConstraintSolverSteps; solverStep++)
{
string filePath = "/home/akreibich/TestRobinCode37/LastSphereConstraintPositions";
using (StreamWriter writer = new StreamWriter(filePath, true)) // 'true' parameter appends to the file
{
writer.WriteLine($"Start of Constraint Solving - Last sphere position: {spherePositionPredictions[0]}");
}
Vector3 initialLastSpherePosition = spherePositionPredictions[0];
if (solveStretchConstraints)
{
constraintSolvingStep.SolveStretchConstraints(spherePositionPredictions, cylinderOrientationPredictions, SpheresCount, worldSpaceBasis, rodElementLength);
......@@ -295,6 +347,13 @@ namespace GuidewireSim
{
collisionSolvingStep.SolveCollisionConstraints(spherePositionPredictions, solverStep, ConstraintSolverSteps);
}
spherePositionPredictions[0] = initialLastSpherePosition;
using (StreamWriter writer = new StreamWriter(filePath, true)) // 'true' parameter appends to the file
{
writer.WriteLine($"End of Constraint Solving - Last sphere position: {spherePositionPredictions[0]}");
}
}
if (solveCollisionConstraints)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment