removed synapse type

This commit is contained in:
Pascal Serrarens 2025-12-03 15:15:42 +01:00
parent 145e033d4c
commit a3d49e330f
8 changed files with 161 additions and 166 deletions

View File

@ -26,6 +26,7 @@ public class NanoBrain_Editor : Editor {
Debug.Log($"Layercount = {this.layers.Count}"); Debug.Log($"Layercount = {this.layers.Count}");
} }
#endregion Start #endregion Start
#region Update #region Update
@ -46,10 +47,10 @@ public class NanoBrain_Editor : Editor {
return; return;
NeuroidLayer currentLayer = new() { ix = layerIx }; NeuroidLayer currentLayer = new() { ix = layerIx };
foreach (Neuroid outputNeuroid in selectedNucleus.outputNeuroids) { foreach (Neuroid outputNeuroid in selectedNucleus.receivers) {
if (outputNeuroid != null) { if (outputNeuroid != null) {
AddToLayer(currentLayer, outputNeuroid); AddToLayer(currentLayer, outputNeuroid);
Debug.Log($"layer {layerIx} nucleus {outputNeuroid.name}"); // Debug.Log($"layer {layerIx} nucleus {outputNeuroid.name}");
} }
} }
if (currentLayer.neuroids.Count > 0) { if (currentLayer.neuroids.Count > 0) {
@ -60,14 +61,14 @@ public class NanoBrain_Editor : Editor {
AddToLayer(currentLayer, selectedNucleus); AddToLayer(currentLayer, selectedNucleus);
this.layers.Add(currentLayer); this.layers.Add(currentLayer);
Debug.Log($"layer {layerIx} nucleus {selectedNucleus.name}"); // Debug.Log($"layer {layerIx} nucleus {selectedNucleus.name}");
layerIx++; layerIx++;
currentLayer = new() { ix = layerIx }; currentLayer = new() { ix = layerIx };
foreach (Nucleus input in selectedNucleus.synapses.Keys) { foreach (Nucleus input in selectedNucleus.synapses.Keys) {
AddToLayer(currentLayer, input); AddToLayer(currentLayer, input);
Debug.Log($"layer {layerIx} nucleus {input.name}"); // Debug.Log($"layer {layerIx} nucleus {input.name}");
} }
if (currentLayer.neuroids.Count > 0) { if (currentLayer.neuroids.Count > 0) {
this.layers.Add(currentLayer); this.layers.Add(currentLayer);
@ -110,32 +111,32 @@ public class NanoBrain_Editor : Editor {
Vector2Int layerNeuroidPos = this.neuroidPositions[layerNeuroid]; Vector2Int layerNeuroidPos = this.neuroidPositions[layerNeuroid];
Vector3 parentPos = new(100 + layerNeuroidPos.x * 100, margin + layerNeuroidPos.y * spacing, 0.1f); Vector3 parentPos = new(100 + layerNeuroidPos.x * 100, margin + layerNeuroidPos.y * spacing, 0.1f);
int i = 0; //int i = 0;
float inputSpacing = 400f / layerNeuroid.synapses.Count; float inputSpacing = 400f / layerNeuroid.synapses.Count;
float inputMargin = 10 + inputSpacing / 2; float inputMargin = 10 + inputSpacing / 2;
// foreach (Synapse synapse in layerNeuroid.synapses.Values) { int minStale = 10000;
// if (synapse.neuroid != null) { foreach ((Nucleus nucleus, float weight) in layerNeuroid.synapses) {
// if (this.neuroidPositions.ContainsKey(synapse.neuroid)) { if (this.neuroidPositions.ContainsKey(nucleus)) {
Vector2Int inputNeuroidPos = this.neuroidPositions[nucleus];
// Vector2Int inputNeuroidPos = this.neuroidPositions[synapse.neuroid];
foreach ((Nucleus neuroid, Synapse synapse) in layerNeuroid.synapses) {
if (neuroid != null) {
if (this.neuroidPositions.ContainsKey(neuroid)) {
Vector2Int inputNeuroidPos = this.neuroidPositions[neuroid];
if (inputNeuroidPos.x == layerNeuroidPos.x + 1) { if (inputNeuroidPos.x == layerNeuroidPos.x + 1) {
Vector3 pos = new(100 + inputNeuroidPos.x * 100, inputMargin + inputNeuroidPos.y * inputSpacing, 0.0f); Vector3 pos = new(100 + inputNeuroidPos.x * 100, inputMargin + inputNeuroidPos.y * inputSpacing, 0.0f);
float brightness = synapse.weight / 10.0f; float brightness = weight / 10.0f;
Handles.color = new Color(brightness, brightness, brightness); Handles.color = new Color(brightness, brightness, brightness);
Handles.DrawLine(parentPos, pos); Handles.DrawLine(parentPos, pos);
} }
} }
if (nucleus is Neuroid neuroid && neuroid.stale < minStale)
minStale = neuroid.stale;
} }
}
if (layerNeuroid.synapses.Count > 0 && minStale > 2 && layerNeuroid.stale < 3)
Debug.LogWarning($"Strange {minStale} is big duing update");
float size = 20; float size = 20;
if (layerNeuroid.IsStale()) if (layerNeuroid.IsStale())
Handles.color = Color.black; Handles.color = Color.darkCyan;
else { else {
float brightness = layerNeuroid.outputValue.magnitude / maxValue; float brightness = layerNeuroid.outputValue.magnitude / maxValue;
Handles.color = new Color(brightness, brightness, brightness); Handles.color = new Color(brightness, brightness, brightness);
@ -154,16 +155,16 @@ public class NanoBrain_Editor : Editor {
Event e = Event.current; Event e = Event.current;
EventType et = e.GetTypeForControl(id); EventType et = e.GetTypeForControl(id);
if (e != null && neuronRect.Contains(e.mousePosition)) { if (e != null && neuronRect.Contains(e.mousePosition)) {
// Process Hover
HandleMouseHover(layerNeuroid, neuronRect); HandleMouseHover(layerNeuroid, neuronRect);
// Process click // Process click
Debug.Log($"{et}");
if (et == EventType.MouseDown && e.button == 0) { if (et == EventType.MouseDown && e.button == 0) {
// Consume the event so the scene doesn't also handle it // Consume the event so the scene doesn't also handle it
e.Use(); e.Use();
HandleDiscClicked(layerNeuroid); HandleDiscClicked(layerNeuroid);
} }
} }
i++; //i++;
} }
} }
} }
@ -199,5 +200,19 @@ public class NanoBrain_Editor : Editor {
BuildLayers(); BuildLayers();
} }
protected virtual void OnSceneGUI() {
NanoBrain brain = target as NanoBrain;
if (brain == null)
return;
// Debug.DrawRay(brain.transform.position, Vector3.forward, Color.magenta);
// Handles.color = Color.green;
// Handles.DrawLine(brain.transform.position, brain.transform.position + Vector3.up);
Vector3 position = brain.transform.position;
Handles.color = Color.yellow;
Vector3 worldForce = brain.transform.TransformDirection(this.currentNucleus.outputValue);
Debug.DrawRay(position, worldForce * 10, Color.yellow);
}
#endregion Update #endregion Update
} }

View File

@ -40,7 +40,7 @@ public class GraphEditorWindow : EditorWindow {
return; return;
NeuroidLayer currentLayer = new() { ix = layerIx }; NeuroidLayer currentLayer = new() { ix = layerIx };
foreach (Neuroid outputNeuroid in selectedNucleus.outputNeuroids) { foreach (Neuroid outputNeuroid in selectedNucleus.receivers) {
if (outputNeuroid != null) { if (outputNeuroid != null) {
AddToLayer(currentLayer, outputNeuroid); AddToLayer(currentLayer, outputNeuroid);
Debug.Log($"layer {layerIx} nucleus {outputNeuroid.name}"); Debug.Log($"layer {layerIx} nucleus {outputNeuroid.name}");
@ -63,7 +63,8 @@ public class GraphEditorWindow : EditorWindow {
// foreach (Synapse synapse in selectedNucleus.synapses.Values) { // foreach (Synapse synapse in selectedNucleus.synapses.Values) {
// Debug.Log($"Synapse {six}"); // Debug.Log($"Synapse {six}");
// Nucleus input = synapse.neuroid; // Nucleus input = synapse.neuroid;
foreach ((Nucleus input, Synapse synapse) in selectedNucleus.synapses) { //foreach ((Nucleus input, Synapse synapse) in selectedNucleus.synapses) {
foreach ((Nucleus input, float weight) in selectedNucleus.synapses) {
if (input != null) { if (input != null) {
AddToLayer(currentLayer, input); AddToLayer(currentLayer, input);
Debug.Log($"layer {layerIx} nucleus {input.name}"); Debug.Log($"layer {layerIx} nucleus {input.name}");
@ -103,8 +104,8 @@ public class GraphEditorWindow : EditorWindow {
// If the output neuroid is visited // If the output neuroid is visited
// Note: this does not yet work for multiple outputs yet (see the use of First()) // Note: this does not yet work for multiple outputs yet (see the use of First())
if (neuroid.outputNeuroids.Count == 0 // make sure the root neuroids are processed directly if (neuroid.receivers.Count == 0 // make sure the root neuroids are processed directly
|| (neuronVisited.Contains(neuroid.outputNeuroids.First()) && neuroid.outputNeuroids.First().layerIx == layerIx - 1)) { || (neuronVisited.Contains(neuroid.receivers.First()) && neuroid.receivers.First().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; neuroid.layerIx = layerIx;
@ -180,14 +181,16 @@ public class GraphEditorWindow : EditorWindow {
// if (this.neuroidPositions.ContainsKey(synapse.neuroid)) { // if (this.neuroidPositions.ContainsKey(synapse.neuroid)) {
// Vector2Int inputNeuroidPos = this.neuroidPositions[synapse.neuroid]; // Vector2Int inputNeuroidPos = this.neuroidPositions[synapse.neuroid];
foreach ((Nucleus neuroid, Synapse synapse) in layerNeuroid.synapses) { //foreach ((Nucleus neuroid, Synapse synapse) in layerNeuroid.synapses) {
foreach ((Nucleus neuroid, float weight) in layerNeuroid.synapses) {
if (neuroid != null) { if (neuroid != null) {
if (this.neuroidPositions.ContainsKey(neuroid)) { if (this.neuroidPositions.ContainsKey(neuroid)) {
Vector2Int inputNeuroidPos = this.neuroidPositions[neuroid]; Vector2Int inputNeuroidPos = this.neuroidPositions[neuroid];
if (inputNeuroidPos.x == layerNeuroidPos.x + 1) { if (inputNeuroidPos.x == layerNeuroidPos.x + 1) {
Vector3 pos = new(100 + inputNeuroidPos.x * 100, inputMargin + inputNeuroidPos.y * inputSpacing, 0.0f); Vector3 pos = new(100 + inputNeuroidPos.x * 100, inputMargin + inputNeuroidPos.y * inputSpacing, 0.0f);
float brightness = synapse.weight / 10.0f; //float brightness = synapse.weight / 10.0f;
float brightness = weight / 10.0f;
Handles.color = new Color(brightness, brightness, brightness); Handles.color = new Color(brightness, brightness, brightness);
Handles.DrawLine(parentPos, pos); Handles.DrawLine(parentPos, pos);
} }
@ -274,7 +277,7 @@ public class GraphEditorWindow : EditorWindow {
if (neuroid == null) if (neuroid == null)
this.allNeuroids = new(); this.allNeuroids = new();
else else
this.allNeuroids = neuroid.net.neuroids; this.allNeuroids = neuroid.brain.neuroids;
Debug.Log($"Neuroncount = {this.allNeuroids.Count}"); Debug.Log($"Neuroncount = {this.allNeuroids.Count}");

View File

@ -9,7 +9,7 @@ public class NanoBrain : MonoBehaviour {
return neuroid; return neuroid;
} }
public void Update() { public void UpdateNeurons() {
foreach (Neuroid neuroid in neuroids) { foreach (Neuroid neuroid in neuroids) {
neuroid.stale++; neuroid.stale++;
if (neuroid.IsStale()) if (neuroid.IsStale())

View File

@ -1,137 +1,90 @@
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using System.Linq;
public class Synapse {
public Synapse(Nucleus neuroid, float weight = 1.0f) {
//this.neuroid = neuroid;
this.weight = weight;
}
//public Nucleus neuroid;
public float weight;
}
// public class NeuroidNetwork {
// public List<Neuroid> neuroids = new();
// public Neuroid AddNeuron(string name) {
// Neuroid neuroid = new(this, name);
// return neuroid;
// }
// public void Update() {
// foreach (Neuroid neuroid in neuroids) {
// neuroid.stale++;
// if (neuroid.IsStale())
// neuroid.outputValue = Vector3.zero;
// }
// }
// }
public class Neuroid : Nucleus { public class Neuroid : Nucleus {
public int stale = 0; public int stale = 0;
//public Vector3 outputValue;
public bool average = false; public bool average = false;
//public bool quadratic = false;
public bool inverse = false; public bool inverse = false;
public float exponent = 1.0f; public float exponent = 1.0f;
//public NeuroidNetwork net; public NanoBrain brain;
public NanoBrain net;
// public Neuroid(NeuroidNetwork net, string name) : base(name) { public Neuroid(NanoBrain brain, string name) : base(name) {
public Neuroid(NanoBrain net, string name) : base(name) { this.brain = brain;
this.net = net; if (this.brain != null)
if (this.net != null) this.brain.neuroids.Add(this);
this.net.neuroids.Add(this);
else else
Debug.LogError("No neuroid network"); Debug.LogError("No neuroid network");
} }
public void AddSynapse(Neuroid input) { public void AddSynapse(Neuroid input) {
input.AddReceiver(this); input.AddReceiver(this);
this.synapses[input] = new(input); this.synapses[input] = 1.0f;
}
// public void AddReceiver(Neuroid receiver) {
// this.outputNeuroids.Add(receiver);
// }
public void ResetWeights() {
foreach (Synapse synapse in this.synapses.Values)
synapse.weight = 1.0f;
} }
public void SetWeight(Neuroid input, float weight) { public void SetWeight(Neuroid input, float weight) {
if (this.synapses.ContainsKey(input)) { this.synapses[input] = weight;
this.synapses[input].weight = weight;
}
else {
this.synapses[input] = new(input, weight);
}
} }
public void GetInputFrom(Neuroid input, float weight = 1.0f) { public void GetInputFrom(Neuroid input, float weight = 1.0f) {
input.AddReceiver(this); input.AddReceiver(this);
this.synapses[input] = new(input, weight); this.synapses[input] = weight;
} }
public void SetInput(Neuroid input) { public void SetInput(Neuroid input) {
if (this.synapses.ContainsKey(input) == false) if (this.synapses.ContainsKey(input) == false)
this.synapses[input] = new(input); this.synapses[input] = 1.0f;
UpdateState(); UpdateState();
} }
public void SetInput(Neuroid input, float weight) { public void SetInput(Neuroid input, float weight) {
if (this.synapses.ContainsKey(input)) { this.synapses[input] = weight;
Synapse synapse = this.synapses[input];
synapse.weight = weight;
}
else
this.synapses[input] = new(input, weight);
UpdateState(); UpdateState();
} }
public void RemoveInputFrom(Neuroid input) { public void RemoveInputFrom(Neuroid input) {
if (this.synapses.Count == 0)
return;
this.synapses.Remove(input); this.synapses.Remove(input);
if (this.synapses.Count == 0) { if (this.synapses.Count == 0) {
// In case this was the last synapse, we reset the output because in this case no updates from synapses will follow. // In case this was the last synapse, we reset the output because in this case no updates from synapses will follow.
this.outputValue = Vector3.zero; this.outputValue = Vector3.zero;
foreach (Neuroid neuroid in this.outputNeuroids) foreach (Neuroid neuroid in this.receivers)
neuroid.SetInput(this); neuroid.SetInput(this);
} }
} }
public virtual void UpdateState() { public virtual void UpdateState() {
// int minStale = 10000;
Vector3 result = Vector3.zero; Vector3 result = Vector3.zero;
foreach ((Nucleus nucleus, Synapse synapse) in this.synapses) { foreach ((Nucleus nucleus, float weight) in this.synapses) {
// foreach (Synapse synapse in this.synapses.Values) { if (nucleus is Neuroid neuroid && neuroid.IsStale())
// if (synapse.neuroid == null) continue;
// Debug.LogWarning(" disconnected synapse");
// if (synapse.value != synapse.neuroid.outputValue)
// Debug.LogWarning("synapse value error");
// Vector3 direction = synapse.value.normalized;
// float magnitude = synapse.value.magnitude;
// Vector3 direction = synapse.neuroid.outputValue.normalized;
// float magnitude = synapse.neuroid.outputValue.magnitude;
Vector3 direction = nucleus.outputValue.normalized; Vector3 direction = nucleus.outputValue.normalized;
float magnitude = nucleus.outputValue.magnitude; float magnitude = nucleus.outputValue.magnitude;
magnitude = synapse.weight * Mathf.Pow(magnitude, exponent); magnitude = weight * Mathf.Pow(magnitude, exponent);
if (inverse && magnitude > 0) if (inverse && magnitude > 0)
magnitude = 1 / magnitude; magnitude = 1 / magnitude;
result += direction * magnitude; result += direction * magnitude;
// if (nucleus is Neuroid neuroid && neuroid.stale < minStale)
// minStale = neuroid.stale;
} }
if (average && this.synapses.Count > 0) if (average && this.synapses.Count > 0)
result /= this.synapses.Count; result /= this.synapses.Count;
this.outputValue = result; this.outputValue = result;
foreach (Neuroid neuroid in this.outputNeuroids)
neuroid.SetInput(this); // if (minStale > 2)
// Debug.LogWarning($"Strange {minStale} is big duing update");
this.stale = 0; this.stale = 0;
foreach (Neuroid receiver in this.receivers)
receiver.SetInput(this);
} }
public bool IsStale() { public bool IsStale() {

View File

@ -4,8 +4,8 @@ using UnityEngine;
public class Nucleus { public class Nucleus {
public string name; public string name;
public readonly Dictionary<Nucleus, Synapse> synapses = new(); public readonly Dictionary<Nucleus, float> synapses = new();
public HashSet<Neuroid> outputNeuroids = new(); public HashSet<Neuroid> receivers = new();
public virtual Vector3 outputValue { get; set; } public virtual Vector3 outputValue { get; set; }
public int layerIx; public int layerIx;
@ -15,7 +15,9 @@ public class Nucleus {
} }
public virtual void AddReceiver(Neuroid receiver) { public virtual void AddReceiver(Neuroid receiver) {
this.outputNeuroids.Add(receiver); //Debug.Log($"add receiver to {this} for {receiver} {receiver.GetHashCode()} {this.receivers.Count} {receiver.synapses.Count}");
receiver.synapses[this] = new(this); this.receivers.Add(receiver);
receiver.synapses[this] = 1.0f; // new(this);
//Debug.Log($"receiver # {this.receivers.Count} synapse count {receiver.synapses.Count}");
} }
} }

View File

@ -32,7 +32,7 @@ public class Perception : Nucleus {
foreach (SensoryNeuroid neuroid in sensoryNeuroids) { foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
if (neuroid != null) { if (neuroid != null) {
neuroid.AddReceiver(receivingNeuroid); neuroid.AddReceiver(receivingNeuroid);
receivingNeuroid.synapses[neuroid] = new(neuroid, weight); receivingNeuroid.synapses[neuroid] = weight; // new(neuroid, weight);
} }
} }
} }
@ -45,7 +45,7 @@ public class Perception : Nucleus {
foreach (SensoryNeuroid neuroid in sensoryNeuroids) { foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
if (neuroid != null && neuroid.velocityNeuroid != null) { if (neuroid != null && neuroid.velocityNeuroid != null) {
neuroid.velocityNeuroid.AddReceiver(receivingNeuroid); neuroid.velocityNeuroid.AddReceiver(receivingNeuroid);
receivingNeuroid.synapses[neuroid] = new(neuroid); receivingNeuroid.synapses[neuroid] = 1.0f; //new(neuroid);
} }
} }
} }
@ -54,22 +54,43 @@ public class Perception : Nucleus {
int availableIx = -1; int availableIx = -1;
int leastInterestingIx = -1; int leastInterestingIx = -1;
for (int i = 0; i < sensoryNeuroids.Length; i++) { for (int i = 0; i < sensoryNeuroids.Length; i++) {
if (sensoryNeuroids[i] == null || sensoryNeuroids[i].IsStale()) if (sensoryNeuroids[i] == null)
availableIx = i; availableIx = i;
else if (sensoryNeuroids[i].receptor.thingId == thingId) { else if (sensoryNeuroids[i].receptor.thingId == thingId) {
sensoryNeuroids[i].receptor.position = localPosition; sensoryNeuroids[i].receptor.position = localPosition;
return; return;
} }
if (sensoryNeuroids[i] != null) { if (availableIx == -1) {
if (sensoryNeuroids[i].IsStale())
leastInterestingIx = i;
else if (sensoryNeuroids[i] != null) {
if (leastInterestingIx == -1 || sensoryNeuroids[leastInterestingIx].receptor.position.magnitude > sensoryNeuroids[i].receptor.position.magnitude) if (leastInterestingIx == -1 || sensoryNeuroids[leastInterestingIx].receptor.position.magnitude > sensoryNeuroids[i].receptor.position.magnitude)
leastInterestingIx = i; leastInterestingIx = i;
} }
} }
}
if (availableIx == -1) if (availableIx == -1)
availableIx = leastInterestingIx; availableIx = leastInterestingIx;
if (availableIx != -1) { if (availableIx != -1) {
// Debug.Log($"new receptor for {thingId}"); if (sensoryNeuroids[availableIx] != null) {
Debug.Log($"replace receptor for {thingId} at {availableIx}");
SensoryNeuroid neuroid = sensoryNeuroids[availableIx];
neuroid.Replace(thingId);
neuroid.name = name;
foreach (Receiver receiver in positionReceivers) {
if (receiver.thingType == 0 || receiver.thingType == thingType)
receiver.neuroid.GetInputFrom(neuroid);
}
foreach (Receiver receiver in velocityReceivers) {
if (receiver.thingType == 0 || receiver.thingType == thingType)
receiver.neuroid.GetInputFrom(neuroid.velocityNeuroid);
}
neuroid.receptor.position = localPosition;
}
else {
Debug.Log($"new receptor for {thingId} at {availableIx}");
SensoryNeuroid neuroid = new(neuroidNet, thingId) { name = name }; SensoryNeuroid neuroid = new(neuroidNet, thingId) { name = name };
foreach (Receiver receiver in positionReceivers) { foreach (Receiver receiver in positionReceivers) {
if (receiver.thingType == 0 || receiver.thingType == thingType) if (receiver.thingType == 0 || receiver.thingType == thingType)
@ -84,12 +105,13 @@ public class Perception : Nucleus {
neuroid.receptor.position = localPosition; neuroid.receptor.position = localPosition;
} }
} }
}
public void RemoveStimulus(int thingId) { public void RemoveStimulus(int thingId) {
for (int i = 0; i < sensoryNeuroids.Length; i++) { for (int i = 0; i < sensoryNeuroids.Length; i++) {
if (sensoryNeuroids[i] != null && sensoryNeuroids[i].receptor.thingId == thingId) { if (sensoryNeuroids[i] != null && sensoryNeuroids[i].receptor.thingId == thingId) {
foreach (Neuroid outputNeuroid in sensoryNeuroids[i].outputNeuroids) foreach (Neuroid receiver in sensoryNeuroids[i].receivers)
outputNeuroid.RemoveInputFrom(sensoryNeuroids[i]); receiver.RemoveInputFrom(sensoryNeuroids[i]);
sensoryNeuroids[i] = null; sensoryNeuroids[i] = null;
return; return;
} }

View File

@ -40,23 +40,23 @@ public class SensoryNeuroid : Neuroid {
this.AddReceiver(velocityNeuroid); this.AddReceiver(velocityNeuroid);
} }
public void Replace(int thingId) {
this.name = "sensory neuroid";
this.receptor.thingId = thingId;
this.receptor.value = Vector3.zero;
this.outputValue = Vector3.zero;
this.receivers = new();
this.AddReceiver(velocityNeuroid);
}
public override void UpdateState() { public override void UpdateState() {
Vector3 result = receptor.value; Vector3 result = receptor.value;
// SensoryNeuroid normally do not have synapses... //foreach ((Nucleus nucleus, Synapse synapse) in this.synapses) {
// foreach (Synapse synapse in this.synapses.Values) { foreach ((Nucleus nucleus, float weight) in this.synapses) {
// if (synapse.neuroid == null)
// Debug.LogWarning(" disconnected synapse");
// // if (synapse.value != synapse.neuroid.outputValue)
// // Debug.LogWarning("synapse value error");
// // Vector3 direction = synapse.value.normalized;
// // float magnitude = synapse.value.magnitude;
// Vector3 direction = synapse.neuroid.outputValue.normalized;
// float magnitude = synapse.neuroid.outputValue.magnitude;
foreach ((Nucleus nucleus, Synapse synapse) in this.synapses) {
Vector3 direction = nucleus.outputValue.normalized; Vector3 direction = nucleus.outputValue.normalized;
float magnitude = nucleus.outputValue.magnitude; float magnitude = nucleus.outputValue.magnitude;
magnitude = synapse.weight * Mathf.Pow(magnitude, exponent); //magnitude = synapse.weight * Mathf.Pow(magnitude, exponent);
magnitude = weight * Mathf.Pow(magnitude, exponent);
if (inverse) if (inverse)
magnitude = 1 / magnitude; magnitude = 1 / magnitude;
result += direction * magnitude; result += direction * magnitude;
@ -65,7 +65,7 @@ public class SensoryNeuroid : Neuroid {
result /= this.synapses.Count + 1; result /= this.synapses.Count + 1;
this.outputValue = result; this.outputValue = result;
foreach (Neuroid neuroid in this.outputNeuroids) foreach (Neuroid neuroid in this.receivers)
neuroid.SetInput(this); neuroid.SetInput(this);
this.stale = 0; this.stale = 0;
} }
@ -82,7 +82,6 @@ public class VelocityNeuroid : Neuroid {
public override void UpdateState() { public override void UpdateState() {
// Assuming only one synapse for now.... // Assuming only one synapse for now....
//Vector3 currentPosition = this.synapses.First().Value.neuroid.outputValue;
Vector3 currentPosition = this.synapses.First().Key.outputValue; Vector3 currentPosition = this.synapses.First().Key.outputValue;
float currentValueTime = Time.time; float currentValueTime = Time.time;
@ -92,10 +91,11 @@ public class VelocityNeuroid : Neuroid {
// No activation function... // No activation function...
this.outputValue = velocity; this.outputValue = velocity;
foreach (Neuroid receiver in outputNeuroids) foreach (Neuroid receiver in receivers)
receiver?.SetInput(this); receiver?.SetInput(this);
this.stale = 0; this.stale = 0;
this.lastValueTime = Time.time; this.lastValueTime = Time.time;
this.lastPosition = currentPosition;
} }
} }

View File

@ -52,7 +52,7 @@ public class Boid : MonoBehaviour {
Vector3 localPosition = neighbour.transform.position - this.transform.position; Vector3 localPosition = neighbour.transform.position - this.transform.position;
int thingId = neighbour.GetInstanceID(); int thingId = neighbour.GetInstanceID();
perception.ProcessStimulus(thingId, BoidType, localPosition); //, neighbour.gameObject.name); perception.ProcessStimulus(thingId, BoidType, localPosition, neighbour.gameObject.name);
} }
} }
@ -63,9 +63,9 @@ public class Boid : MonoBehaviour {
Vector3 desiredLocalSpace = -this.transform.InverseTransformPoint(desiredWorldSpace); Vector3 desiredLocalSpace = -this.transform.InverseTransformPoint(desiredWorldSpace);
perception.ProcessStimulus(777, BoundaryType, desiredLocalSpace, "Boundary"); perception.ProcessStimulus(777, BoundaryType, desiredLocalSpace, "Boundary");
} }
else { // else {
perception.RemoveStimulus(777); // perception.RemoveStimulus(777);
} // }
Vector3 worldForce = this.transform.TransformDirection(totalForce.outputValue); Vector3 worldForce = this.transform.TransformDirection(totalForce.outputValue);
@ -82,7 +82,7 @@ public class Boid : MonoBehaviour {
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
} }
neuroidNet.Update(); neuroidNet.UpdateNeurons();
} }
Vector3 ClosestPointOnBoundsSurface(Bounds b, Vector3 p) { Vector3 ClosestPointOnBoundsSurface(Bounds b, Vector3 p) {
@ -96,18 +96,18 @@ public class Boid : MonoBehaviour {
return b.center + d * m; return b.center + d * m;
} }
void OnDrawGizmosSelected() { // void OnDrawGizmosSelected() {
if (sc == null) // if (sc == null)
return; // return;
Gizmos.DrawWireSphere(this.transform.position, sc.perceptionDistance); // Gizmos.DrawWireSphere(this.transform.position, sc.perceptionDistance);
Gizmos.color = Color.yellow; // Gizmos.color = Color.yellow;
Vector3 worldForce = this.transform.TransformDirection(totalForce.outputValue); // Vector3 worldForce = this.transform.TransformDirection(totalForce.outputValue);
Gizmos.DrawRay(transform.position, worldForce * 10); // Gizmos.DrawRay(transform.position, worldForce * 10);
// Gizmos.color = Color.magenta; // // Gizmos.color = Color.magenta;
// Gizmos.DrawRay(transform.position, this.transform.TransformDirection(avoidance.outputValue) * 10); // // Gizmos.DrawRay(transform.position, this.transform.TransformDirection(avoidance.outputValue) * 10);
// Debug.Log($"Avoidance {roaming.avoidance.outputValue} Roaming {roaming.output.outputValue} Total {totalForce.outputValue}"); // // Debug.Log($"Avoidance {roaming.avoidance.outputValue} Roaming {roaming.output.outputValue} Total {totalForce.outputValue}");
// Debug.Log($"WorldForce {worldForce} velocity {velocity} inertia {sc.inertia}"); // // Debug.Log($"WorldForce {worldForce} velocity {velocity} inertia {sc.inertia}");
Gizmos.color = Color.blue; // Gizmos.color = Color.blue;
Gizmos.DrawRay(transform.position, this.velocity * 10); // Gizmos.DrawRay(transform.position, this.velocity * 10);
} // }
} }