Needs tuning

This commit is contained in:
Pascal Serrarens 2025-12-17 12:41:25 +01:00
parent 0cee652110
commit 65359ecbfa
9 changed files with 973 additions and 1207 deletions

View File

@ -61,7 +61,7 @@ public class Nucleus {
#region Runtime state (not serialized)
public NanoBrainObj brain { get; protected set; }
public NanoBrainObj brain { get; set; }
public virtual Vector3 outputValue { get; set; }
@ -110,8 +110,10 @@ public class Nucleus {
receiver.nucleus.synapses.RemoveAll(s => s.nucleus == nucleus);
}
nucleus.brain.nuclei.RemoveAll(n => n == nucleus);
nucleus.brain.GarbageCollection();
if (nucleus.brain != null) {
nucleus.brain.nuclei.RemoveAll(n => n == nucleus);
nucleus.brain.GarbageCollection();
}
}
public void GetInputFrom(Nucleus input, float weight = 1.0f) {

View File

@ -123,19 +123,19 @@ public class Perceptoid : Neuroid {
public void UpdateState(int thingId, Vector3 receptorValue) {
this.thingId = thingId;
Vector3 result = receptorValue;
foreach (Synapse synapse in this.synapses) {
Nucleus nucleus = synapse.nucleus;
float weight = synapse.weight;
Vector3 direction = nucleus.outputValue.normalized;
float magnitude = nucleus.outputValue.magnitude;
// foreach (Synapse synapse in this.synapses) {
// Nucleus nucleus = synapse.nucleus;
// float weight = synapse.weight;
// Vector3 direction = nucleus.outputValue.normalized;
// float magnitude = nucleus.outputValue.magnitude;
magnitude = weight * Mathf.Pow(magnitude, exponent);
if (inverse)
magnitude = 1 / magnitude;
result += direction * magnitude;
}
if (average && this.synapses.Count > 0)
result /= this.synapses.Count + 1;
// magnitude = weight * Mathf.Pow(magnitude, exponent);
// if (inverse)
// magnitude = 1 / magnitude;
// result += direction * magnitude;
// }
// if (average && this.synapses.Count > 0)
// result /= this.synapses.Count + 1;
this.outputValue = result;
foreach (Receiver receiver in this.receivers)

View File

@ -40,7 +40,7 @@ public class Receptor {
Debug.Log("No perceptoid selected, stimulus is ignored");
return;
}
Debug.Log($"Stimulus {thingId} {selectedPerceptoid.thingId}");
//Debug.Log($"Stimulus {thingId} {selectedPerceptoid.thingId}");
selectedPerceptoid.UpdateState(this.thingId, this.localPosition);
}
}

View File

@ -228,7 +228,7 @@ public class NanoBrainInspector : Editor {
private void DrawGraph() {
float size = 20;
Vector3 position = new(200, 210, 0);
Vector3 position = new(150, 210, 0);
DrawReceivers(this.currentNucleus, position, size);
DrawSynapses(this.currentNucleus, position, size);
@ -263,7 +263,7 @@ public class NanoBrainInspector : Editor {
if (receiverNucleus == null)
continue;
Vector3 pos = new(100, margin + row * spacing, 0.0f);
Vector3 pos = new(50, margin + row * spacing, 0.0f);
Handles.color = Color.white;
Handles.DrawLine(parentPos, pos);
@ -294,7 +294,7 @@ public class NanoBrainInspector : Editor {
foreach (Synapse receiver in nucleus.synapses) {
Nucleus receiverNucleus = receiver.nucleus;
Vector3 pos = new(300, margin + row * spacing, 0.0f);
Vector3 pos = new(250, margin + row * spacing, 0.0f);
Handles.color = Color.white;
Handles.DrawLine(parentPos, pos);
@ -400,8 +400,7 @@ public class NanoBrainInspector : Editor {
this.currentNucleus.name = EditorGUILayout.TextField(this.currentNucleus.name);
if (this.currentNucleus is Perceptoid currentPerceptoid)
currentPerceptoid.thingType = EditorGUILayout.IntField("Thing Type", currentPerceptoid.thingType);
if (this.currentNucleus is Neuroid neuroid) {
else if (this.currentNucleus is Neuroid neuroid) {
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Activation Curve", GUILayout.Width(150));
if (neuroid.curveMax > 0)
@ -457,7 +456,7 @@ public class NanoBrainInspector : Editor {
if (this.gameObject != null) {
Vector3 worldVector = this.gameObject.transform.TransformVector(this.currentNucleus.outputValue);
Debug.DrawRay(this.gameObject.transform.position, worldVector, Color.yellow );
Debug.DrawRay(this.gameObject.transform.position, worldVector, Color.yellow);
}
});
@ -467,11 +466,15 @@ public class NanoBrainInspector : Editor {
protected virtual void AddInputNeuron(Nucleus nucleus) {
Neuroid newNeuroid = new(this.brain, "New neuron");
newNeuroid.AddReceiver(nucleus);
this.currentNucleus = newNeuroid;
BuildLayers();
}
protected virtual void DeleteNeuron(Nucleus nucleus) {
this.currentNucleus = nucleus.brain.root;
if (nucleus == null)
return;
if (nucleus.brain != null)
this.currentNucleus = nucleus.brain.root;
foreach (Receiver receiver in nucleus.receivers) {
if (receiver.nucleus != null) {
this.currentNucleus = receiver.nucleus;
@ -485,18 +488,29 @@ public class NanoBrainInspector : Editor {
protected virtual void AddPerceptoid(Nucleus nucleus) {
Perceptoid newPerceptoid = new(this.brain, 0, "New Perceptoid");
newPerceptoid.AddReceiver(nucleus);
this.currentNucleus = newPerceptoid;
BuildLayers();
}
protected virtual void ConnectNucleus(Nucleus nucleus) {
if (this.currentNucleus.brain == null)
return;
string[] names = this.currentNucleus.brain.perceptei.Select(i => i.name).ToArray();
//string[] names = this.currentNucleus.brain.perceptei.Select(i => i.name).ToArray();
IEnumerable<string> perceptei = this.currentNucleus.brain.perceptei.Select(i => i.name);
IEnumerable<string> nuclei = this.currentNucleus.brain.nuclei.Select(i => i.name);
string[] names = perceptei.Concat(nuclei).ToArray();
int selectedIndex = -1;
selectedIndex = EditorGUILayout.Popup("Connect to", selectedIndex, names);
if (selectedIndex >= 0 && selectedIndex < this.currentNucleus.brain.perceptei.Count) {
Nucleus n = this.currentNucleus.brain.perceptei[selectedIndex];
n.AddReceiver(this.currentNucleus);
if (selectedIndex >= 0) {
if (selectedIndex < perceptei.Count()) {
Nucleus n = this.currentNucleus.brain.perceptei[selectedIndex];
n.AddReceiver(this.currentNucleus);
}
else {
Nucleus n = this.currentNucleus.brain.nuclei[selectedIndex - perceptei.Count()];
n.AddReceiver(this.currentNucleus);
}
}
}
@ -544,7 +558,7 @@ public class NanoBrainInspector : Editor {
#region Update
private void UpdateLayout(float containerWidth) {
if (containerWidth > 800f) {
if (containerWidth > 700f) {
mainContainer.style.flexDirection = FlexDirection.Row;
inspectorContainer.style.width = 400; // fixed sidebar width
inspectorContainer.style.flexGrow = 0;

View File

@ -71,13 +71,16 @@ public class NanoBrainObj : ScriptableObject, ISerializationCallbackReceiver {
MarkNuclei(visitedNuclei, this.root);
Debug.Log($"Garbage collection found {visitedNuclei.Count} Nuclei");
this.nuclei.RemoveAll(nucleus => visitedNuclei.Contains(nucleus) == false);
this.perceptei.RemoveAll(perceptoid => visitedNuclei.Contains(perceptoid) == false);
this.perceptei.RemoveAll(perceptoid => visitedNuclei.Contains(perceptoid) == false);
}
public void MarkNuclei(HashSet<Nucleus> visitedNuclei, Nucleus nucleus) {
if (nucleus is null)
return;
if (nucleus.brain == null)
nucleus.brain = this;
visitedNuclei.Add(nucleus);
if (nucleus.synapses != null) {
HashSet<Synapse> visitedSynapses = new();
@ -89,5 +92,16 @@ public class NanoBrainObj : ScriptableObject, ISerializationCallbackReceiver {
}
nucleus.synapses.RemoveAll(synapse => visitedSynapses.Contains(synapse) == false);
}
if (nucleus.receivers != null) {
HashSet<Receiver> visitedReceivers = new();
foreach (Receiver receiver in nucleus.receivers) {
if (receiver != null && receiver.nucleus != null) {
visitedReceivers.Add(receiver);
visitedNuclei.Add(receiver.nucleus);
//MarkNuclei(visitedNuclei, receiver.nucleus);
}
}
nucleus.receivers.RemoveAll(receiver => visitedReceivers.Contains(receiver) == false);
}
}
}

View File

@ -371,13 +371,13 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 0464906885ae3494f8fd0314719fb2db, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::SwarmControl
speed: 2
inertia: 0.5
speed: 1
inertia: 0.8
alignmentForce: 2
cohesionForce: 2
avoidanceForce: 1
separationDistance: 0.3
perceptionDistance: 1
perceptionDistance: 2
boundaryForce: 5
spaceSize: {x: 10, y: 10, z: 10}
boundaryWidth: {x: 1, y: 1, z: 1}
@ -393,7 +393,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: ec888ca5333d45a438f9f417fa5ce135, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::SwarmSpawn
count: 30
count: 100
boidPrefab: {fileID: 8702527964058765413, guid: f9c706268554ce449a8773675b2864b8, type: 3}
spawnAreaSize: {x: 0.5, y: 0.5, z: 0.5}
minDelay: 0.05

View File

@ -22,8 +22,42 @@ MonoBehaviour:
synapses:
- nucleusId: -112538112
weight: 1
curvePreset: 0
curve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
curveMax: 0
receivers: []
nucleusType:
_curvePreset: 0
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 1
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 1
inSlope: 1
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
curveMax: 1
average: 0
inverse: 0
exponent: 1
@ -32,9 +66,25 @@ MonoBehaviour:
synapses:
- nucleusId: 407735232
weight: -1
curvePreset: 0
curve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
curveMax: 0
receivers:
- nucleusId: -1707533328
nucleusType:
_curvePreset: 0
curve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
curveMax: 0
average: 0
inverse: 0
exponent: 1
@ -45,6 +95,14 @@ MonoBehaviour:
receivers:
- nucleusId: -112538112
nucleusType: Perceptoid
_curvePreset: 0
curve:
serializedVersion: 2
m_Curve: []
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
curveMax: 0
average: 0
inverse: 0
exponent: 1

View File

@ -39,6 +39,7 @@ public class Boid : MonoBehaviour {
continue;
Vector3 localPosition = this.transform.InverseTransformPoint(neighbour.transform.position);
localPosition = localPosition.normalized * (localPosition.magnitude - sc.separationDistance);
//Debug.DrawRay(this.transform.position, this.transform.TransformDirection(localPosition), Color.magenta);
int thingId = neighbour.GetInstanceID();
@ -61,13 +62,13 @@ public class Boid : MonoBehaviour {
this.velocity = this.velocity.normalized * sc.speed;
else
this.velocity = this.transform.forward * sc.speed;
Debug.DrawRay(this.transform.position, this.velocity, Color.blue);
//Debug.DrawRay(this.transform.position, this.velocity, Color.blue);
this.transform.position += this.velocity * Time.deltaTime;
if (this.velocity != Vector3.zero) {
Quaternion targetRotation = Quaternion.LookRotation(this.velocity);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2f); // Adjust the speed of rotation
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 5f); // Adjust the speed of rotation
}
nanoBrain.brain.UpdateNuclei();

File diff suppressed because it is too large Load Diff