improved sensoryneuroids
This commit is contained in:
parent
cb04a7645b
commit
2e803179e3
@ -38,15 +38,18 @@ public class GraphEditorWindow : EditorWindow {
|
|||||||
|
|
||||||
foreach (Neuroid neuroid in neuroids) {
|
foreach (Neuroid neuroid in neuroids) {
|
||||||
// If this neuroid is not visited while its output neuroid is visited
|
// If this neuroid is not visited while its output neuroid is visited
|
||||||
if (!neuronVisited.Contains(neuroid) && (neuronVisited.Contains(neuroid.outputNeuroid) || neuroid.outputNeuroid == null)) {
|
if (!neuronVisited.Contains(neuroid) && (neuroid.outputNeuroid == null ||
|
||||||
|
(neuronVisited.Contains(neuroid.outputNeuroid) && neuroid.outputNeuroid.layerIx == layerIx - 1))) {
|
||||||
// Add it to the next layer
|
// Add it to the next layer
|
||||||
currentLayer.neuroids.Add(neuroid);
|
currentLayer.neuroids.Add(neuroid);
|
||||||
|
neuroid.layerIx = layerIx;
|
||||||
// Register it as visited
|
// Register it as visited
|
||||||
neuronVisited.Add(neuroid);
|
neuronVisited.Add(neuroid);
|
||||||
// Store its position
|
// Store its position
|
||||||
Vector2Int neuroidPosition = new(layerIx, neuroidIx);
|
Vector2Int neuroidPosition = new(layerIx, neuroidIx);
|
||||||
neuroidPositions[neuroid] = neuroidPosition;
|
neuroidPositions[neuroid] = neuroidPosition;
|
||||||
neuroidIx++;
|
neuroidIx++;
|
||||||
|
Debug.Log($"Layer {layerIx} neuron {neuroidIx} id {neuroid.id} {neuroid.name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,41 +87,8 @@ public class GraphEditorWindow : EditorWindow {
|
|||||||
|
|
||||||
foreach (NeuroidLayer layer in layers)
|
foreach (NeuroidLayer layer in layers)
|
||||||
DrawLayer(layer);
|
DrawLayer(layer);
|
||||||
// int column = 100;
|
|
||||||
// int row = 200;
|
|
||||||
// Vector3 parentPos = new(column, row, 0.1f);
|
|
||||||
// Handles.DrawSolidDisc(parentPos, Vector3.forward, 15);
|
|
||||||
|
|
||||||
// DrawLayer(2, parentPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void DrawLayer(int layerIx, Vector3 parentPos) {
|
|
||||||
// int column = layerIx * 100;
|
|
||||||
// int nodeCount = currentNeuroid.synapses.Count;
|
|
||||||
// float maxValue = 0;
|
|
||||||
// foreach (Synapse synapse in currentNeuroid.synapses.Values) {
|
|
||||||
// float value = synapse.value.magnitude;
|
|
||||||
// if (value > maxValue)
|
|
||||||
// maxValue = value;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// float spacing = 200f / nodeCount; // Calculate spacing
|
|
||||||
// float margin = 100 + spacing / 3;
|
|
||||||
// int i = 0;
|
|
||||||
// foreach (Synapse synapse in currentNeuroid.synapses.Values) {
|
|
||||||
// Vector3 pos = new(column, margin + i * spacing);
|
|
||||||
|
|
||||||
// float brightness = synapse.weight / 10.0f;
|
|
||||||
// Handles.color = new Color(brightness, brightness, brightness);
|
|
||||||
// Handles.DrawLine(parentPos - Vector3.forward, pos);
|
|
||||||
|
|
||||||
// float size = synapse.value.magnitude / maxValue * 20;
|
|
||||||
// Handles.color = Color.white;
|
|
||||||
// Handles.DrawSolidDisc(pos, Vector3.forward, size);
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private void DrawLayer(NeuroidLayer layer) {
|
private void DrawLayer(NeuroidLayer layer) {
|
||||||
int column = layer.ix * 100;
|
int column = layer.ix * 100;
|
||||||
int nodeCount = layer.neuroids.Count;
|
int nodeCount = layer.neuroids.Count;
|
||||||
@ -151,7 +121,7 @@ public class GraphEditorWindow : EditorWindow {
|
|||||||
float size = layerNeuroid.outputValue.magnitude / maxValue * 20;
|
float size = layerNeuroid.outputValue.magnitude / maxValue * 20;
|
||||||
Handles.color = Color.white;
|
Handles.color = Color.white;
|
||||||
Handles.DrawSolidDisc(parentPos, Vector3.forward, size);
|
Handles.DrawSolidDisc(parentPos, Vector3.forward, size);
|
||||||
Rect neuronRect = new(parentPos.x-size, parentPos.y-size, size*2, size*2);
|
Rect neuronRect = new(parentPos.x - size, parentPos.y - size, size * 2, size * 2);
|
||||||
if (neuronRect.Contains(Event.current.mousePosition))
|
if (neuronRect.Contains(Event.current.mousePosition))
|
||||||
HandleMouseHover(layerNeuroid, neuronRect);
|
HandleMouseHover(layerNeuroid, neuronRect);
|
||||||
i++;
|
i++;
|
||||||
|
|||||||
@ -26,6 +26,8 @@ public class Neuroid {
|
|||||||
public int id;
|
public int id;
|
||||||
public string name;
|
public string name;
|
||||||
|
|
||||||
|
public int layerIx;
|
||||||
|
|
||||||
public readonly Dictionary<int, Synapse> synapses = new();
|
public readonly Dictionary<int, Synapse> synapses = new();
|
||||||
|
|
||||||
public Vector3 outputValue;
|
public Vector3 outputValue;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
class Receptor {
|
public class Receptor {
|
||||||
public SensoryNeuroid neuroid;
|
public SensoryNeuroid neuroid;
|
||||||
public void SetValue(Vector3 value) {
|
public void SetValue(Vector3 value) {
|
||||||
if (neuroid != null) {
|
if (neuroid != null) {
|
||||||
@ -10,10 +10,15 @@ class Receptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SensoryNeuroid : Neuroid {
|
public class SensoryNeuroid : Neuroid {
|
||||||
public Receptor receptor;
|
public Receptor receptor;
|
||||||
|
|
||||||
public SensoryNeuroid(NeuroidNetwork id) : base(id) {
|
public SensoryNeuroid(NeuroidNetwork net, int id) : base(net) {
|
||||||
|
this.name = "sensory neuroid";
|
||||||
|
this.id = id;
|
||||||
|
this.receptor = new Receptor {
|
||||||
|
neuroid = this
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,8 +1,7 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
public class Boid : MonoBehaviour
|
public class Boid : MonoBehaviour {
|
||||||
{
|
|
||||||
public float speed = 0.2f;
|
public float speed = 0.2f;
|
||||||
public int neighbourCount = 0;
|
public int neighbourCount = 0;
|
||||||
public float inertia = 0.2f;
|
public float inertia = 0.2f;
|
||||||
@ -20,6 +19,8 @@ public class Boid : MonoBehaviour
|
|||||||
|
|
||||||
readonly Collider[] results = new Collider[10];
|
readonly Collider[] results = new Collider[10];
|
||||||
|
|
||||||
|
public SensoryNeuroid[] neighbourSensor = new SensoryNeuroid[6];
|
||||||
|
|
||||||
public NeuroidNetwork neuroidNet = new();
|
public NeuroidNetwork neuroidNet = new();
|
||||||
public Neuroid bodyVector;
|
public Neuroid bodyVector;
|
||||||
public Neuroid cohesion;
|
public Neuroid cohesion;
|
||||||
@ -32,15 +33,17 @@ public class Boid : MonoBehaviour
|
|||||||
|
|
||||||
public int id;
|
public int id;
|
||||||
|
|
||||||
void Awake()
|
void Awake() {
|
||||||
{
|
|
||||||
this.id = this.GetInstanceID();
|
this.id = this.GetInstanceID();
|
||||||
|
|
||||||
sc = FindFirstObjectByType<SwarmControl>();
|
sc = FindFirstObjectByType<SwarmControl>();
|
||||||
|
|
||||||
bounds = new(sc.transform.position, sc.spaceSize - 2 * sc.boundaryWidth);
|
bounds = new(sc.transform.position, sc.spaceSize - 2 * sc.boundaryWidth);
|
||||||
|
|
||||||
|
//neighbourSensor = new(neuroidNet) { name = "Neighbour", id = 879 };
|
||||||
|
|
||||||
cohesion = new(neuroidNet) { name = "Cohesion", mode = Neuroid.Mode.Sum };
|
cohesion = new(neuroidNet) { name = "Cohesion", mode = Neuroid.Mode.Sum };
|
||||||
|
//cohesion.GetInputFrom(neighbourSensor);
|
||||||
alignment = new(neuroidNet) { name = "Alignment", mode = Neuroid.Mode.Average };
|
alignment = new(neuroidNet) { name = "Alignment", mode = Neuroid.Mode.Average };
|
||||||
separation = new(neuroidNet) { name = "Separation", mode = Neuroid.Mode.Sum };
|
separation = new(neuroidNet) { name = "Separation", mode = Neuroid.Mode.Sum };
|
||||||
target = new(neuroidNet) { name = "Target", mode = Neuroid.Mode.Sum };
|
target = new(neuroidNet) { name = "Target", mode = Neuroid.Mode.Sum };
|
||||||
@ -55,8 +58,7 @@ public class Boid : MonoBehaviour
|
|||||||
totalForce.GetInputFrom(boundary, sc.boundaryForce);
|
totalForce.GetInputFrom(boundary, sc.boundaryForce);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update()
|
void Update() {
|
||||||
{
|
|
||||||
Physics.OverlapSphereNonAlloc(this.transform.position, 10, results);
|
Physics.OverlapSphereNonAlloc(this.transform.position, 10, results);
|
||||||
neighbourCount = 0;
|
neighbourCount = 0;
|
||||||
|
|
||||||
@ -64,13 +66,11 @@ public class Boid : MonoBehaviour
|
|||||||
alignment.ResetWeights();
|
alignment.ResetWeights();
|
||||||
separation.ResetWeights();
|
separation.ResetWeights();
|
||||||
|
|
||||||
foreach (Collider c in results)
|
foreach (Collider c in results) {
|
||||||
{
|
|
||||||
if (c == null)
|
if (c == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (c as CapsuleCollider != null)
|
if (c as CapsuleCollider != null) {
|
||||||
{
|
|
||||||
Boid neighbour = c.GetComponentInParent<Boid>();
|
Boid neighbour = c.GetComponentInParent<Boid>();
|
||||||
if (neighbour == null || neighbour == this)
|
if (neighbour == null || neighbour == this)
|
||||||
continue;
|
continue;
|
||||||
@ -79,12 +79,15 @@ public class Boid : MonoBehaviour
|
|||||||
Vector3 relativeVelocity = neighbour.velocity - this.velocity;
|
Vector3 relativeVelocity = neighbour.velocity - this.velocity;
|
||||||
|
|
||||||
int id = neighbour.GetInstanceID();
|
int id = neighbour.GetInstanceID();
|
||||||
|
Receptor receptor = GetReceptor(id);
|
||||||
|
if (receptor != null) {
|
||||||
|
receptor.SetValue(localPosition);
|
||||||
|
}
|
||||||
Vector3 separationForce = -localPosition / localPosition.sqrMagnitude;
|
Vector3 separationForce = -localPosition / localPosition.sqrMagnitude;
|
||||||
// which is equivalent to -(localPosition.normalized / localPosition.magnitude)
|
// which is equivalent to -(localPosition.normalized / localPosition.magnitude)
|
||||||
|
|
||||||
separation.SetInput(id, separationForce, sc.separationDistance);
|
separation.SetInput(id, separationForce, sc.separationDistance);
|
||||||
cohesion.SetInput(id, localPosition, sc.cohesionForce);
|
//cohesion.SetInput(id, localPosition, sc.cohesionForce);
|
||||||
alignment.SetInput(id, relativeVelocity, sc.alignmentForce);
|
alignment.SetInput(id, relativeVelocity, sc.alignmentForce);
|
||||||
|
|
||||||
neighbourCount++;
|
neighbourCount++;
|
||||||
@ -92,8 +95,7 @@ public class Boid : MonoBehaviour
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Vector3 spaceLocalPosition = sc.transform.InverseTransformPoint(this.transform.position);
|
//Vector3 spaceLocalPosition = sc.transform.InverseTransformPoint(this.transform.position);
|
||||||
if (!bounds.Contains(this.transform.position))
|
if (!bounds.Contains(this.transform.position)) {
|
||||||
{
|
|
||||||
Vector3 point = this.transform.position;
|
Vector3 point = this.transform.position;
|
||||||
// Vector3 distanceOutside = Vector3.Max(bounds.min - this.transform.position, this.transform.position - bounds.max);
|
// Vector3 distanceOutside = Vector3.Max(bounds.min - this.transform.position, this.transform.position - bounds.max);
|
||||||
// // Ensure value is > 0 (but isn't this already)
|
// // Ensure value is > 0 (but isn't this already)
|
||||||
@ -109,7 +111,7 @@ public class Boid : MonoBehaviour
|
|||||||
outside = direction * magnitude;
|
outside = direction * magnitude;
|
||||||
|
|
||||||
boundary.SetInput(id, outside, sc.boundaryForce);
|
boundary.SetInput(id, outside, sc.boundaryForce);
|
||||||
Debug.Log($"boundary {this.transform.position} {outside} force = {outside * sc.boundaryForce}");
|
// Debug.Log($"boundary {this.transform.position} {outside} force = {outside * sc.boundaryForce}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 totalForceVector = totalForce.outputValue;
|
Vector3 totalForceVector = totalForce.outputValue;
|
||||||
@ -120,11 +122,28 @@ public class Boid : MonoBehaviour
|
|||||||
|
|
||||||
this.transform.position += this.velocity * Time.deltaTime;
|
this.transform.position += this.velocity * Time.deltaTime;
|
||||||
|
|
||||||
if (this.velocity != Vector3.zero)
|
if (this.velocity != Vector3.zero) {
|
||||||
{
|
|
||||||
Quaternion targetRotation = Quaternion.LookRotation(this.velocity);
|
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 * 2f); // Adjust the speed of rotation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Receptor GetReceptor(int id) {
|
||||||
|
int availableIx = -1;
|
||||||
|
for (int i = 0; i < neighbourSensor.Length; i++) {
|
||||||
|
if (neighbourSensor[i] == null)
|
||||||
|
availableIx = i;
|
||||||
|
else if (neighbourSensor[i].id == id)
|
||||||
|
return neighbourSensor[i].receptor;
|
||||||
|
}
|
||||||
|
if (availableIx != -1) {
|
||||||
|
Debug.Log($"new receptor for {id}");
|
||||||
|
SensoryNeuroid neuroid = new(neuroidNet, id);
|
||||||
|
cohesion.GetInputFrom(neuroid);
|
||||||
|
neighbourSensor[availableIx] = neuroid;
|
||||||
|
return neuroid.receptor;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
4
NanoBrain-Unity.slnx
Normal file
4
NanoBrain-Unity.slnx
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<Solution>
|
||||||
|
<Project Path="Assembly-CSharp.csproj" />
|
||||||
|
<Project Path="Assembly-CSharp-Editor.csproj" />
|
||||||
|
</Solution>
|
||||||
Loading…
x
Reference in New Issue
Block a user