Perceptoid pool starts to work
This commit is contained in:
parent
dc8ac7ef9b
commit
4e8d10f1bd
@ -11,12 +11,16 @@ public class Perceptoid : Neuroid {
|
||||
|
||||
[SerializeField]
|
||||
public int thingType;
|
||||
public int thingId;
|
||||
|
||||
public override void Rebuild(NanoBrainObj brain) {
|
||||
base.Rebuild(brain);
|
||||
this.receptor = new Receptor() {
|
||||
neuroid = this
|
||||
};
|
||||
//this.receptor = new Receptor(this);
|
||||
this.receptor = Perceptoid.GetReceptor(brain, thingType);
|
||||
if (this.receptor == null)
|
||||
this.receptor = new Receptor(this);
|
||||
else
|
||||
this.receptor.perceptei.Add(this);
|
||||
}
|
||||
|
||||
public override void Deserialize(Nucleus nucleus) {
|
||||
@ -57,9 +61,7 @@ public class Perceptoid : Neuroid {
|
||||
|
||||
this.nucleusType = nameof(Perceptoid);
|
||||
this.name = name;
|
||||
this.receptor = new Receptor {
|
||||
neuroid = this
|
||||
};
|
||||
this.receptor = new Receptor(this);
|
||||
}
|
||||
|
||||
public Perceptoid(NanoBrainObj brain, int thingType, string name = "sensor") : base(name) {
|
||||
@ -73,8 +75,7 @@ public class Perceptoid : Neuroid {
|
||||
this.nucleusType = nameof(Perceptoid);
|
||||
this.name = name;
|
||||
this.thingType = thingType;
|
||||
this.receptor = new Receptor {
|
||||
neuroid = this,
|
||||
this.receptor = new Receptor(this) {
|
||||
thingType = thingType
|
||||
};
|
||||
this.velocityNeuroid = new(brain, name + ": velocity");
|
||||
@ -119,6 +120,31 @@ public class Perceptoid : Neuroid {
|
||||
this.stale = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
if (receiver.nucleus is Neuroid neuroid)
|
||||
neuroid.SetInput(this);
|
||||
this.stale = 0;
|
||||
}
|
||||
|
||||
|
||||
public static Perceptoid GetPerception(NanoBrainObj brain, int thingType = 0) {
|
||||
foreach (Nucleus nucleus in brain.nuclei) {
|
||||
if (nucleus is Perceptoid perceptoid && (thingType == 0 || perceptoid.thingType == thingType))
|
||||
|
||||
@ -4,13 +4,18 @@ using UnityEngine;
|
||||
|
||||
public class Receptor {
|
||||
|
||||
public Neuroid neuroid;
|
||||
public List<Perceptoid> perceptoids;
|
||||
private Neuroid neuroid;
|
||||
public List<Perceptoid> perceptei = new();
|
||||
|
||||
public int thingId;
|
||||
public int thingType;
|
||||
public Vector3 localPosition;
|
||||
|
||||
public Receptor(Perceptoid perceptoid) {
|
||||
this.neuroid = perceptoid;
|
||||
this.perceptei.Add(perceptoid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Local position of the thing
|
||||
/// </summary>
|
||||
@ -27,7 +32,29 @@ public class Receptor {
|
||||
public virtual void ProcessStimulus(int thingId, Vector3 localPosition) {
|
||||
this.thingId = thingId;
|
||||
this.localPosition = localPosition;
|
||||
neuroid.UpdateState();
|
||||
//perceptoids[0].UpdateState();
|
||||
///neuroid.UpdateState();
|
||||
|
||||
Perceptoid selectedPerceptoid = null;
|
||||
foreach (Perceptoid perceptoid in this.perceptei) {
|
||||
if (perceptoid.thingId == this.thingId) {
|
||||
selectedPerceptoid = perceptoid;
|
||||
break;
|
||||
}
|
||||
else if (perceptoid.isSleeping)
|
||||
selectedPerceptoid = perceptoid;
|
||||
else if (selectedPerceptoid == null) {
|
||||
selectedPerceptoid = perceptoid;
|
||||
}
|
||||
else if (selectedPerceptoid.isSleeping == false) {
|
||||
if (perceptoid.receptor.position.magnitude < selectedPerceptoid.receptor.position.magnitude)
|
||||
selectedPerceptoid = perceptoid;
|
||||
}
|
||||
}
|
||||
if (selectedPerceptoid == null) {
|
||||
Debug.Log("No perceptoid selected, stimulus is ignored");
|
||||
return;
|
||||
}
|
||||
Debug.Log($"Stimulus {thingId} {selectedPerceptoid.thingId}");
|
||||
selectedPerceptoid.UpdateState(this.thingId, this.localPosition);
|
||||
}
|
||||
}
|
||||
@ -40,11 +40,9 @@ public class SensoryNeuroid : Neuroid {
|
||||
|
||||
public SensoryNeuroid(NanoBrainObj brain, int thingId, string name = "sensor") : base(brain, name) {
|
||||
this.name = name + ": position";
|
||||
this.receptor = new Receptor {
|
||||
neuroid = this,
|
||||
//perceptoids[0] = this,
|
||||
thingType = thingId
|
||||
};
|
||||
// this.receptor = new Receptor(this) {
|
||||
// thingType = thingId
|
||||
// };
|
||||
this.velocityNeuroid = new(brain, name + ": velocity");
|
||||
// The velocity neuroid received position data from this
|
||||
this.AddReceiver(velocityNeuroid);
|
||||
|
||||
@ -237,38 +237,6 @@ public class NanoBrainInspector : Editor {
|
||||
DrawNucleus(this.currentNucleus, position, this.currentNucleus.outputValue.magnitude, 20);
|
||||
}
|
||||
|
||||
private void DrawNucleus(Nucleus nucleus, Vector3 position, float maxValue, float size) {
|
||||
if (nucleus.isSleeping)
|
||||
Handles.color = Color.darkRed;
|
||||
else {
|
||||
float brightness = nucleus.outputValue.magnitude / maxValue;
|
||||
Handles.color = new Color(brightness, brightness, brightness);
|
||||
}
|
||||
Handles.DrawSolidDisc(position, Vector3.forward, size);
|
||||
Vector3 labelPos = position - Vector3.down * (size + 0.2f); // below disc along up axis
|
||||
GUIStyle style = new GUIStyle(EditorStyles.label) {
|
||||
alignment = TextAnchor.UpperCenter,
|
||||
normal = { textColor = Color.white },
|
||||
fontStyle = FontStyle.Bold
|
||||
};
|
||||
Handles.Label(labelPos, nucleus.name, style);
|
||||
|
||||
Rect neuronRect = new(position.x - size, position.y - size, size * 2, size * 2);
|
||||
int id = GUIUtility.GetControlID(FocusType.Passive);
|
||||
Event e = Event.current;
|
||||
EventType et = e.GetTypeForControl(id);
|
||||
if (e != null && neuronRect.Contains(e.mousePosition)) {
|
||||
// Process Hover
|
||||
HandleMouseHover(nucleus, neuronRect);
|
||||
// Process click
|
||||
if (e.type == EventType.MouseDown && e.button == 0) {
|
||||
// Consume the event so the scene doesn't also handle it
|
||||
e.Use();
|
||||
HandleClicked(nucleus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawReceivers(Nucleus nucleus, Vector3 parentPos, float size) {
|
||||
int nodeCount = nucleus.receivers.Count;
|
||||
|
||||
@ -290,6 +258,8 @@ public class NanoBrainInspector : Editor {
|
||||
int row = 0;
|
||||
foreach (Receiver receiver in nucleus.receivers) {
|
||||
Nucleus receiverNucleus = receiver.nucleus;
|
||||
if (receiverNucleus == null)
|
||||
continue;
|
||||
|
||||
Vector3 pos = new(100, margin + row * spacing, 0.0f);
|
||||
Handles.color = Color.white;
|
||||
@ -331,104 +301,68 @@ public class NanoBrainInspector : Editor {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private void DrawLayer(NeuroidLayer layer) {
|
||||
int nodeCount = layer.neuroids.Count;
|
||||
|
||||
// Determine the maximum value in this layer
|
||||
// This is used to 'scale' the output value colors of the nuclei
|
||||
float maxValue = 0;
|
||||
foreach (Nucleus nucleus in layer.neuroids) {
|
||||
if (nucleus is Neuroid neuroid) {
|
||||
float value = neuroid.outputValue.magnitude;
|
||||
if (value > maxValue)
|
||||
maxValue = value;
|
||||
}
|
||||
private void DrawNucleus(Nucleus nucleus, Vector3 position, float maxValue, float size) {
|
||||
if (nucleus.isSleeping)
|
||||
Handles.color = Color.darkRed;
|
||||
else {
|
||||
float brightness = nucleus.outputValue.magnitude / maxValue;
|
||||
Handles.color = new Color(brightness, brightness, brightness);
|
||||
}
|
||||
Handles.DrawSolidDisc(position, Vector3.forward, size);
|
||||
Vector3 labelPos = position - Vector3.down * (size + 0.2f); // below disc along up axis
|
||||
GUIStyle style = new GUIStyle(EditorStyles.label) {
|
||||
alignment = TextAnchor.UpperCenter,
|
||||
normal = { textColor = Color.white },
|
||||
fontStyle = FontStyle.Bold
|
||||
};
|
||||
Handles.Label(labelPos, nucleus.name, style);
|
||||
|
||||
// Determine the spacing of the nuclei in the layer
|
||||
float spacing = 400f / nodeCount;
|
||||
float margin = 10 + spacing / 2;
|
||||
|
||||
foreach (Nucleus layerNucleus in layer.neuroids) {
|
||||
Vector2Int layerNeuroidPos = this.neuroidPositions[layerNucleus];
|
||||
Vector3 parentPos = new(100 + layerNeuroidPos.x * 100, margin + layerNeuroidPos.y * spacing, 0.1f);
|
||||
|
||||
float inputSpacing = 400f / layerNucleus.synapses.Count;
|
||||
float inputMargin = 10 + inputSpacing / 2;
|
||||
int minStale = 10000;
|
||||
foreach (Synapse synapse in layerNucleus.synapses) {
|
||||
Nucleus nucleus = synapse.nucleus;
|
||||
if (nucleus != null) {
|
||||
if (this.neuroidPositions.ContainsKey(nucleus)) {
|
||||
Vector2Int inputNeuroidPos = this.neuroidPositions[nucleus];
|
||||
if (inputNeuroidPos.x == layerNeuroidPos.x + 1) {
|
||||
Vector3 pos = new(100 + inputNeuroidPos.x * 100, inputMargin + inputNeuroidPos.y * inputSpacing, 0.0f);
|
||||
|
||||
Handles.color = Color.white;
|
||||
Handles.DrawLine(parentPos, pos);
|
||||
}
|
||||
}
|
||||
if (nucleus is Neuroid neuroid && neuroid.stale < minStale)
|
||||
minStale = neuroid.stale;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float size = 20;
|
||||
if (layerNucleus == this.currentNucleus) {
|
||||
Handles.color = Color.white;
|
||||
Handles.DrawSolidDisc(parentPos, Vector3.forward, size + 2);
|
||||
}
|
||||
DrawNucleus(layerNucleus, parentPos, maxValue, size);
|
||||
// if (layerNucleus.isSleeping)
|
||||
// Handles.color = Color.darkRed;
|
||||
// else {
|
||||
// float brightness = layerNucleus.outputValue.magnitude / maxValue;
|
||||
// Handles.color = new Color(brightness, brightness, brightness);
|
||||
// }
|
||||
// Handles.DrawSolidDisc(parentPos, Vector3.forward, size);
|
||||
// Vector3 labelPos = parentPos - Vector3.down * (size + 0.2f); // below disc along up axis
|
||||
// GUIStyle style = new GUIStyle(EditorStyles.label) {
|
||||
// alignment = TextAnchor.UpperCenter,
|
||||
// normal = { textColor = Color.white },
|
||||
// fontStyle = FontStyle.Bold
|
||||
// };
|
||||
// Handles.Label(labelPos, layerNucleus.name, style);
|
||||
|
||||
Rect neuronRect = new(parentPos.x - size, parentPos.y - size, size * 2, size * 2);
|
||||
int id = GUIUtility.GetControlID(FocusType.Passive);
|
||||
Event e = Event.current;
|
||||
EventType et = e.GetTypeForControl(id);
|
||||
if (e != null && neuronRect.Contains(e.mousePosition)) {
|
||||
// Process Hover
|
||||
HandleMouseHover(layerNucleus, neuronRect);
|
||||
// Process click
|
||||
if (e.type == EventType.MouseDown && e.button == 0) {
|
||||
// Consume the event so the scene doesn't also handle it
|
||||
e.Use();
|
||||
HandleClicked(layerNucleus);
|
||||
}
|
||||
Rect neuronRect = new(position.x - size, position.y - size, size * 2, size * 2);
|
||||
int id = GUIUtility.GetControlID(FocusType.Passive);
|
||||
Event e = Event.current;
|
||||
EventType et = e.GetTypeForControl(id);
|
||||
if (e != null && neuronRect.Contains(e.mousePosition)) {
|
||||
// Process Hover
|
||||
HandleMouseHover(nucleus, neuronRect);
|
||||
// Process click
|
||||
if (e.type == EventType.MouseDown && e.button == 0) {
|
||||
// Consume the event so the scene doesn't also handle it
|
||||
e.Use();
|
||||
HandleClicked(nucleus);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private void HandleMouseHover(Nucleus neuroid, Rect rect) {
|
||||
private void HandleMouseHover(Nucleus nucleus, Rect rect) {
|
||||
GUIContent tooltip;
|
||||
if (neuroid is SensoryNeuroid sensoryNeuroid) {
|
||||
if (nucleus is SensoryNeuroid sensoryNeuroid) {
|
||||
tooltip = new(
|
||||
$"{sensoryNeuroid.name}" +
|
||||
$"\nThing {sensoryNeuroid.receptor.thingType}" +
|
||||
$"\nValue: {neuroid.outputValue}" +
|
||||
$"\nStale: {neuroid.stale}");
|
||||
$"\nValue: {nucleus.outputValue}" +
|
||||
$"\nStale: {nucleus.stale}");
|
||||
}
|
||||
else if (nucleus is Perceptoid perceptoid) {
|
||||
if (perceptoid.receptor != null) {
|
||||
tooltip = new(
|
||||
$"{perceptoid.name}" +
|
||||
$"\nType {perceptoid.receptor.thingType}" +
|
||||
$" Thing {perceptoid.thingId}" +
|
||||
$"\nValue: {nucleus.outputValue}");
|
||||
}
|
||||
else {
|
||||
tooltip = new(
|
||||
$"{perceptoid.name}" +
|
||||
$"\nThing {perceptoid.thingId}" +
|
||||
$"\nValue: {nucleus.outputValue}");
|
||||
}
|
||||
}
|
||||
else {
|
||||
tooltip = new(
|
||||
$"{neuroid.name}" +
|
||||
$"\nsynapse count {neuroid.synapses.Count}" +
|
||||
$"\nValue: {neuroid.outputValue}" +
|
||||
$"\nStale: {neuroid.stale}");
|
||||
$"{nucleus.name}" +
|
||||
$"\nsynapse count {nucleus.synapses.Count}" +
|
||||
$"\nValue: {nucleus.outputValue}" +
|
||||
$"\nStale: {nucleus.stale}");
|
||||
}
|
||||
|
||||
Vector2 mousePosition = Event.current.mousePosition;
|
||||
@ -445,7 +379,6 @@ public class NanoBrainInspector : Editor {
|
||||
BuildLayers();
|
||||
}
|
||||
|
||||
|
||||
void DrawInspector(VisualElement inspectorContainer) {
|
||||
if (inspectorContainer == null)
|
||||
return;
|
||||
@ -518,9 +451,14 @@ public class NanoBrainInspector : Editor {
|
||||
}
|
||||
|
||||
protected virtual void DeleteNeuron(Nucleus nucleus) {
|
||||
this.currentNucleus = nucleus.receivers[0].nucleus;
|
||||
this.currentNucleus = nucleus.brain.root;
|
||||
foreach (Receiver receiver in nucleus.receivers) {
|
||||
if (receiver.nucleus != null) {
|
||||
this.currentNucleus = receiver.nucleus;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Nucleus.Delete(nucleus);
|
||||
//Rebuild(inspectorContainer);
|
||||
BuildLayers();
|
||||
}
|
||||
|
||||
|
||||
@ -393,7 +393,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: ec888ca5333d45a438f9f417fa5ce135, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::SwarmSpawn
|
||||
count: 3
|
||||
count: 30
|
||||
boidPrefab: {fileID: 8702527964058765413, guid: f9c706268554ce449a8773675b2864b8, type: 3}
|
||||
spawnAreaSize: {x: 0.5, y: 0.5, z: 0.5}
|
||||
minDelay: 0.05
|
||||
|
||||
@ -49,4 +49,5 @@ MonoBehaviour:
|
||||
inverse: 0
|
||||
exponent: 1
|
||||
thingType: 1
|
||||
thingId: 0
|
||||
rootId: -1707533328
|
||||
|
||||
@ -23,7 +23,7 @@ MonoBehaviour:
|
||||
- nucleusId: -112538112
|
||||
weight: 1
|
||||
- nucleusId: 1938577052
|
||||
weight: 1
|
||||
weight: 10
|
||||
receivers: []
|
||||
nucleusType:
|
||||
average: 0
|
||||
@ -43,9 +43,9 @@ MonoBehaviour:
|
||||
- id: 1938577052
|
||||
_name: Cohesion
|
||||
synapses:
|
||||
- nucleusId: -1408496896
|
||||
- nucleusId: -1420275136
|
||||
weight: 1
|
||||
- nucleusId: -133566816
|
||||
- nucleusId: -1266532688
|
||||
weight: 1
|
||||
receivers:
|
||||
- nucleusId: -1707533328
|
||||
@ -64,7 +64,8 @@ MonoBehaviour:
|
||||
inverse: 0
|
||||
exponent: 1
|
||||
thingType: 1
|
||||
- id: -1408496896
|
||||
thingId: 0
|
||||
- id: -1420275136
|
||||
_name: Boid1
|
||||
synapses: []
|
||||
receivers:
|
||||
@ -74,15 +75,16 @@ MonoBehaviour:
|
||||
inverse: 0
|
||||
exponent: 1
|
||||
thingType: 2
|
||||
- id: -133566816
|
||||
thingId: 0
|
||||
- id: -1266532688
|
||||
_name: Boid2
|
||||
synapses: []
|
||||
receivers:
|
||||
- nucleusId: 27651644
|
||||
- nucleusId: 1938577052
|
||||
nucleusType: Perceptoid
|
||||
average: 0
|
||||
inverse: 0
|
||||
exponent: 1
|
||||
thingType: 2
|
||||
thingId: 0
|
||||
rootId: -1707533328
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user