Disabled Receptor
This commit is contained in:
parent
0258ef1197
commit
0d268edd6d
51
Cluster.cs
51
Cluster.cs
@ -42,22 +42,22 @@ public class Cluster : INucleus {
|
||||
}
|
||||
|
||||
private void ClonePrefab() {
|
||||
IReceptor[] nuclei = this.prefab.nuclei.ToArray();
|
||||
INucleus[] prefabNuclei = this.prefab.nuclei.ToArray();
|
||||
// first clone the nuclei without their connections
|
||||
foreach (IReceptor nucleus in this.prefab.nuclei)
|
||||
foreach (INucleus nucleus in this.prefab.nuclei)
|
||||
nucleus.ShallowCloneTo(this);
|
||||
IReceptor[] clonedNuclei = this.nuclei.ToArray();
|
||||
INucleus[] clonedNuclei = this.nuclei.ToArray();
|
||||
|
||||
// Now clone the connections
|
||||
for (int nucleusIx = 0; nucleusIx < nuclei.Length; nucleusIx++) {
|
||||
IReceptor receptor = nuclei[nucleusIx];
|
||||
IReceptor clonedReceptor = clonedNuclei[nucleusIx];
|
||||
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
|
||||
INucleus receptor = prefabNuclei[nucleusIx];
|
||||
INucleus clonedReceptor = clonedNuclei[nucleusIx];
|
||||
if (clonedReceptor == null)
|
||||
continue;
|
||||
|
||||
// Copy the receivers, which will also create the synapses
|
||||
foreach (INucleus receiver in receptor.receivers) {
|
||||
int ix = GetNucleusIndex(nuclei, receiver);
|
||||
int ix = GetNucleusIndex(prefabNuclei, receiver);
|
||||
if (ix < 0)
|
||||
continue;
|
||||
|
||||
@ -79,8 +79,8 @@ public class Cluster : INucleus {
|
||||
}
|
||||
|
||||
// Copy nucleus arrays
|
||||
for (int nucleusIx = 0; nucleusIx < nuclei.Length; nucleusIx++) {
|
||||
IReceptor prefabReceptor = nuclei[nucleusIx];
|
||||
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
|
||||
IReceptor prefabReceptor = prefabNuclei[nucleusIx];
|
||||
if (prefabReceptor is not INucleus prefabNucleus)
|
||||
continue;
|
||||
|
||||
@ -93,7 +93,7 @@ public class Cluster : INucleus {
|
||||
NucleusArray clonedArray = new(prefabNucleus.array.nuclei.Length, "array");
|
||||
int arrayIx = 0;
|
||||
foreach (IReceptor prefabArrayNucleus in prefabNucleus.array.nuclei) {
|
||||
int arrayNucleusIx = GetNucleusIndex(nuclei, prefabArrayNucleus);
|
||||
int arrayNucleusIx = GetNucleusIndex(prefabNuclei, prefabArrayNucleus);
|
||||
IReceptor clonedArrayNucleus = clonedNuclei[arrayNucleusIx];
|
||||
clonedArray.nuclei[arrayIx] = clonedArrayNucleus;
|
||||
arrayIx++;
|
||||
@ -102,7 +102,7 @@ public class Cluster : INucleus {
|
||||
}
|
||||
else {
|
||||
// The others will refer to the array created for the first nucleus in the array
|
||||
int firstNucleusIx = GetNucleusIndex(nuclei, prefabNucleus.array.nuclei[0]);
|
||||
int firstNucleusIx = GetNucleusIndex(prefabNuclei, prefabNucleus.array.nuclei[0]);
|
||||
INucleus clonedFirstNucleus = clonedNuclei[firstNucleusIx] as INucleus;
|
||||
clonedNucleus.array = clonedFirstNucleus.array;
|
||||
}
|
||||
@ -110,26 +110,26 @@ public class Cluster : INucleus {
|
||||
}
|
||||
|
||||
// Sort the nuclei in a correct evaluation order
|
||||
private List<IReceptor> TopologicalSort(List<IReceptor> nodes) {
|
||||
private List<IReceptor> TopologicalSort(List<INucleus> nodes) {
|
||||
Dictionary<IReceptor, int> inDegree = new();
|
||||
foreach (IReceptor node in nodes)
|
||||
inDegree[node] = 0; // Initialize in-degree to zero
|
||||
|
||||
// Calculate in-degrees
|
||||
foreach (IReceptor node in nodes) {
|
||||
foreach (INucleus node in nodes) {
|
||||
foreach (INucleus receiver in node.receivers)
|
||||
inDegree[receiver]++;
|
||||
}
|
||||
|
||||
Queue<IReceptor> queue = new();
|
||||
foreach (IReceptor node in nodes) {
|
||||
Queue<INucleus> queue = new();
|
||||
foreach (INucleus node in nodes) {
|
||||
if (inDegree[node] == 0) // Nodes with no dependencies
|
||||
queue.Enqueue(node);
|
||||
}
|
||||
|
||||
List<IReceptor> sortedOrder = new();
|
||||
while (queue.Count > 0) {
|
||||
IReceptor current = queue.Dequeue();
|
||||
INucleus current = queue.Dequeue();
|
||||
sortedOrder.Add(current); // Process the node
|
||||
|
||||
foreach (INucleus receiver in current.receivers) {
|
||||
@ -185,7 +185,7 @@ public class Cluster : INucleus {
|
||||
public Cluster parent { get; set; }
|
||||
|
||||
[SerializeReference]
|
||||
public List<IReceptor> nuclei = new();
|
||||
public List<INucleus> nuclei = new();
|
||||
// the nuclei sorted using topological sorting
|
||||
// to ensure that the cluster is computer in the right order
|
||||
public List<IReceptor> sortedNuclei;
|
||||
@ -235,13 +235,22 @@ public class Cluster : INucleus {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Nucleus GetNucleus(string nucleusName) {
|
||||
foreach (IReceptor receptor in this.nuclei) {
|
||||
if (receptor is Nucleus nucleus)
|
||||
if (nucleus.name == nucleusName)
|
||||
return nucleus;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#region Synapses
|
||||
|
||||
[SerializeField]
|
||||
private List<Synapse> _synapses = new();
|
||||
public List<Synapse> synapses => _synapses;
|
||||
|
||||
public Synapse AddSynapse(IReceptor sendingNucleus, float weight = 1.0f) {
|
||||
public Synapse AddSynapse(INucleus sendingNucleus, float weight = 1.0f) {
|
||||
Synapse synapse = new(sendingNucleus, weight);
|
||||
this._synapses.Add(synapse);
|
||||
return synapse;
|
||||
@ -335,7 +344,7 @@ public class Cluster : INucleus {
|
||||
foreach (IReceptor receptor in this.sortedNuclei) {
|
||||
if (receptor is INucleus nucleus && nucleus != this.inputs[0]) {
|
||||
//if (nucleus.isSleeping == false)
|
||||
nucleus.UpdateStateIsolated();
|
||||
nucleus.UpdateStateIsolated();
|
||||
}
|
||||
}
|
||||
this.outputValue = this.output.outputValue;
|
||||
@ -357,11 +366,11 @@ public class Cluster : INucleus {
|
||||
|
||||
public void UpdateNuclei() {
|
||||
this.stale++;
|
||||
if (this.stale > 5)
|
||||
if (this.stale > 5)
|
||||
_outputValue = Vector3.zero;
|
||||
|
||||
//foreach (IReceptor nucleus in this.prefab.nuclei)
|
||||
foreach (IReceptor nucleus in this.nuclei)
|
||||
foreach (INucleus nucleus in this.nuclei)
|
||||
nucleus.UpdateNuclei();
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ public class ClusterPrefab : ScriptableObject {
|
||||
// The ScriptableObject asset from which the runtime object has been created
|
||||
|
||||
[SerializeReference]
|
||||
public List<IReceptor> nuclei = new();
|
||||
public List<INucleus> nuclei = new();
|
||||
|
||||
|
||||
public virtual INucleus output => this.nuclei[0] as INucleus;
|
||||
@ -33,7 +33,7 @@ public class ClusterPrefab : ScriptableObject {
|
||||
// This is an invariant and should be ensured before the nucleus is used
|
||||
// because output requires it.
|
||||
public void EnsureInitialization() {
|
||||
nuclei ??= new List<IReceptor>();
|
||||
nuclei ??= new List<INucleus>();
|
||||
if (nuclei.Count == 0)
|
||||
new Neuron(this, "Output"); // Every cluster should have at least 1 neuron
|
||||
}
|
||||
@ -74,7 +74,7 @@ public class ClusterPrefab : ScriptableObject {
|
||||
}
|
||||
|
||||
public virtual void UpdateNuclei() {
|
||||
foreach (IReceptor nucleus in this.nuclei)
|
||||
foreach (INucleus nucleus in this.nuclei)
|
||||
nucleus.UpdateNuclei();
|
||||
}
|
||||
}
|
||||
@ -210,7 +210,7 @@ public class ClusterInspector : Editor {
|
||||
// Draw selected Nucleus
|
||||
if (expandArray) {
|
||||
float maxValue = 0;
|
||||
foreach (IReceptor nucleus in this.currentNucleus.array.nuclei) {
|
||||
foreach (INucleus nucleus in this.currentNucleus.array.nuclei) {
|
||||
float value = length(nucleus.outputValue);
|
||||
if (value > maxValue)
|
||||
maxValue = value;
|
||||
@ -231,7 +231,7 @@ public class ClusterInspector : Editor {
|
||||
Handles.color = Color.black;
|
||||
Handles.DrawAAConvexPolygon(verts);
|
||||
int row = 0;
|
||||
foreach (IReceptor nucleus in this.currentNucleus.array.nuclei) {
|
||||
foreach (INucleus nucleus in this.currentNucleus.array.nuclei) {
|
||||
Vector3 pos = new(150, margin + row * spacing, 0.0f);
|
||||
Handles.color = Color.white;
|
||||
// The selected nucleus highlight ring
|
||||
@ -344,7 +344,7 @@ public class ClusterInspector : Editor {
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawNucleus(IReceptor nucleus, Vector3 position, float maxValue, float size) {
|
||||
private void DrawNucleus(INucleus nucleus, Vector3 position, float maxValue, float size) {
|
||||
Color color;
|
||||
if (nucleus.isSleeping)
|
||||
color = Color.darkRed;
|
||||
@ -359,7 +359,7 @@ public class ClusterInspector : Editor {
|
||||
DrawNucleus(nucleus, position, maxValue, size, color);
|
||||
}
|
||||
|
||||
private void DrawNucleus(IReceptor nucleus, Vector3 position, float maxValue, float size, Color color) {
|
||||
private void DrawNucleus(INucleus nucleus, Vector3 position, float maxValue, float size, Color color) {
|
||||
if (nucleus is MemoryCell memory) {
|
||||
Handles.color = Color.white;
|
||||
Handles.DrawWireDisc(position + Vector3.right * 10, Vector3.forward, size);
|
||||
@ -426,7 +426,7 @@ public class ClusterInspector : Editor {
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleMouseHover(IReceptor nucleus, Rect rect) {
|
||||
private void HandleMouseHover(INucleus nucleus, Rect rect) {
|
||||
GUIContent tooltip;
|
||||
// if (nucleus is INucleus n) {
|
||||
// tooltip = new(
|
||||
@ -692,7 +692,7 @@ public class ClusterInspector : Editor {
|
||||
// Nucleus n = this.currentNucleus.brain.nuclei[selectedIndex - perceptei.Count()];
|
||||
// n.AddReceiver(this.currentNucleus);
|
||||
// }
|
||||
IReceptor receptor = cluster.nuclei[selectedIndex];
|
||||
INucleus receptor = cluster.nuclei[selectedIndex];
|
||||
receptor.AddReceiver(this.currentNucleus);
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ public interface INucleus : IReceptor {
|
||||
|
||||
// Senders
|
||||
public List<Synapse> synapses { get; }
|
||||
public Synapse AddSynapse(IReceptor sender, float weight = 1.0f);
|
||||
public Synapse AddSynapse(INucleus sender, float weight = 1.0f);
|
||||
|
||||
public NucleusArray array { get; set; }
|
||||
|
||||
@ -25,9 +25,7 @@ public interface INucleus : IReceptor {
|
||||
public void UpdateStateIsolated(float3 inputValue);
|
||||
|
||||
#endregion dynamic state
|
||||
}
|
||||
|
||||
public interface IReceptor {
|
||||
#region static
|
||||
|
||||
public string name { get; set; }
|
||||
@ -54,3 +52,6 @@ public interface IReceptor {
|
||||
public IReceptor Clone();
|
||||
}
|
||||
|
||||
public interface IReceptor {
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
|
||||
public abstract class Nucleus : IReceptor {
|
||||
public abstract class Nucleus : INucleus {
|
||||
[SerializeField]
|
||||
protected string _name;
|
||||
public virtual string name {
|
||||
@ -42,7 +42,7 @@ public abstract class Nucleus : IReceptor {
|
||||
private List<Synapse> _synapses = new();
|
||||
public List<Synapse> synapses => _synapses;
|
||||
|
||||
public Synapse AddSynapse(IReceptor sendingNucleus, float weight = 1.0f) {
|
||||
public Synapse AddSynapse(INucleus sendingNucleus, float weight = 1.0f) {
|
||||
Synapse synapse = new(sendingNucleus, weight);
|
||||
this.synapses.Add(synapse);
|
||||
return synapse;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/*
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
@ -154,4 +155,5 @@ public class Receptor : IReceptor {
|
||||
if (isSleeping)
|
||||
this._outputValue = Vector3.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
100
ReceptorArray.cs
100
ReceptorArray.cs
@ -1,3 +1,4 @@
|
||||
/*
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
@ -31,55 +32,56 @@ public class ReceptorArray {
|
||||
//selectedReceiver.outputValue = newLocalPositionVector;
|
||||
|
||||
|
||||
/*
|
||||
int receiverIx = 0;
|
||||
INucleus selectedReceiver = null;
|
||||
int selectedReceiverIx = 0;
|
||||
foreach (INucleus receiver in this.receivers) {
|
||||
if (thingIds[receiverIx] == thingId) {
|
||||
// We found an existing receiver for this thing
|
||||
selectedReceiver = receiver;
|
||||
selectedReceiverIx = receiverIx;
|
||||
// Do not look any further
|
||||
break;
|
||||
}
|
||||
else if (receiver.isSleeping) {
|
||||
// A sleeping receiver is not active and can therefore always be used
|
||||
selectedReceiver = receiver;
|
||||
selectedReceiverIx = receiverIx;
|
||||
// Look further because we may find an existing receiver for this thing
|
||||
}
|
||||
else if (selectedReceiver == null) {
|
||||
// If we haven't found a receiver yet, just start by taking the first
|
||||
selectedReceiver = receiver;
|
||||
selectedReceiverIx = receiverIx;
|
||||
}
|
||||
else if (selectedReceiver.isSleeping == false) {
|
||||
// If no existing or sleeping receiver is found, we look for
|
||||
// the receiver with the furthest/least interesting stimulus
|
||||
if (length(receiver.outputValue) < length(selectedReceiver.outputValue)) {
|
||||
// Debug.Log($"{selectedReceiver.name}[{selectedReceiverIx}] {length(selectedReceiver.outputValue)}" +
|
||||
// $" {receiver.name}[{receiverIx}] {length(receiver.outputValue)} ");
|
||||
selectedReceiver = receiver;
|
||||
selectedReceiverIx = receiverIx;
|
||||
}
|
||||
}
|
||||
receiverIx++;
|
||||
}
|
||||
if (selectedReceiverIx >= thingIds.Length)
|
||||
return;
|
||||
|
||||
// int receiverIx = 0;
|
||||
// INucleus selectedReceiver = null;
|
||||
// int selectedReceiverIx = 0;
|
||||
// foreach (INucleus receiver in this.receivers) {
|
||||
// if (thingIds[receiverIx] == thingId) {
|
||||
// // We found an existing receiver for this thing
|
||||
// selectedReceiver = receiver;
|
||||
// selectedReceiverIx = receiverIx;
|
||||
// // Do not look any further
|
||||
// break;
|
||||
// }
|
||||
// else if (receiver.isSleeping) {
|
||||
// // A sleeping receiver is not active and can therefore always be used
|
||||
// selectedReceiver = receiver;
|
||||
// selectedReceiverIx = receiverIx;
|
||||
// // Look further because we may find an existing receiver for this thing
|
||||
// }
|
||||
// else if (selectedReceiver == null) {
|
||||
// // If we haven't found a receiver yet, just start by taking the first
|
||||
// selectedReceiver = receiver;
|
||||
// selectedReceiverIx = receiverIx;
|
||||
// }
|
||||
// else if (selectedReceiver.isSleeping == false) {
|
||||
// // If no existing or sleeping receiver is found, we look for
|
||||
// // the receiver with the furthest/least interesting stimulus
|
||||
// if (length(receiver.outputValue) < length(selectedReceiver.outputValue)) {
|
||||
// // Debug.Log($"{selectedReceiver.name}[{selectedReceiverIx}] {length(selectedReceiver.outputValue)}" +
|
||||
// // $" {receiver.name}[{receiverIx}] {length(receiver.outputValue)} ");
|
||||
// selectedReceiver = receiver;
|
||||
// selectedReceiverIx = receiverIx;
|
||||
// }
|
||||
// }
|
||||
// receiverIx++;
|
||||
// }
|
||||
// if (selectedReceiverIx >= thingIds.Length)
|
||||
// return;
|
||||
|
||||
thingIds[selectedReceiverIx] = thingId;
|
||||
if (thingName != null) {
|
||||
string baseName = selectedReceiver.name;
|
||||
int colonPos = selectedReceiver.name.IndexOf(":");
|
||||
if (colonPos > 0)
|
||||
baseName = selectedReceiver.name.Substring(0, colonPos);
|
||||
selectedReceiver.name = baseName + ": " + thingName;
|
||||
}
|
||||
Debug.Log($"Receiver {selectedReceiver.name}[{selectedReceiverIx}] for thing {thingId}");
|
||||
selectedReceiver.parent.UpdateStateIsolated();
|
||||
*/
|
||||
// thingIds[selectedReceiverIx] = thingId;
|
||||
// if (thingName != null) {
|
||||
// string baseName = selectedReceiver.name;
|
||||
// int colonPos = selectedReceiver.name.IndexOf(":");
|
||||
// if (colonPos > 0)
|
||||
// baseName = selectedReceiver.name.Substring(0, colonPos);
|
||||
// selectedReceiver.name = baseName + ": " + thingName;
|
||||
// }
|
||||
// Debug.Log($"Receiver {selectedReceiver.name}[{selectedReceiverIx}] for thing {thingId}");
|
||||
// selectedReceiver.parent.UpdateStateIsolated();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
@ -5,17 +5,17 @@ public class SelectorBrain : NanoBrain {
|
||||
public Vector3 input2;
|
||||
public Vector3 output;
|
||||
|
||||
public Receptor receptor1;
|
||||
public Receptor receptor2;
|
||||
public Nucleus receptor;
|
||||
//public Nucleus receptor2;
|
||||
|
||||
protected void Awake() {
|
||||
receptor1 = new Receptor(this.brain, "Receptor", "Selector");
|
||||
receptor2 = new Receptor(this.brain, "Receptor", "Selector");
|
||||
receptor = this.brain.GetNucleus("Selector");
|
||||
//receptor2 = this.brain.GetNucleus("Selector");
|
||||
}
|
||||
|
||||
protected void Update() {
|
||||
receptor1.ProcessStimulus(0, input1);
|
||||
receptor2.ProcessStimulus(1, input2);
|
||||
receptor.ProcessStimulus(0, input1);
|
||||
receptor.ProcessStimulus(1, input2);
|
||||
output = this.brain.outputValue;
|
||||
|
||||
this.brain.UpdateNuclei();
|
||||
|
||||
11
Synapse.cs
11
Synapse.cs
@ -3,19 +3,12 @@ using UnityEngine;
|
||||
|
||||
[Serializable]
|
||||
public class Synapse {
|
||||
// Support access to cluster of basic nucleus
|
||||
//public IReceptor nucleus => basicNucleus;
|
||||
|
||||
|
||||
//[SerializeReference]
|
||||
//public Cluster cluster;
|
||||
|
||||
[SerializeReference]
|
||||
public IReceptor nucleus;
|
||||
public INucleus nucleus;
|
||||
|
||||
public float weight;
|
||||
|
||||
public Synapse(IReceptor nucleus, float weight = 1.0f) {
|
||||
public Synapse(INucleus nucleus, float weight = 1.0f) {
|
||||
this.nucleus = nucleus;
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user