Refactoring
This commit is contained in:
parent
1771ab7d23
commit
7ce787f5db
@ -18,3 +18,6 @@ csharp_new_line_between_query_expression_clauses = true
|
|||||||
|
|
||||||
# Limit the number of characters in a line
|
# Limit the number of characters in a line
|
||||||
max_line_length = 100 # This setting does not enforce it; it's a guideline.
|
max_line_length = 100 # This setting does not enforce it; it's a guideline.
|
||||||
|
|
||||||
|
[*.{cs,vb}]
|
||||||
|
dotnet_diagnostic.IDE1006.severity = none
|
||||||
@ -52,6 +52,7 @@
|
|||||||
<Compile Include="Assets/NanoBrain/NeuroidBehaviour.cs" />
|
<Compile Include="Assets/NanoBrain/NeuroidBehaviour.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/SensoryNeuroid.cs" />
|
<Compile Include="Assets/NanoBrain/SensoryNeuroid.cs" />
|
||||||
<Compile Include="Assets/Scenes/Boids/Scripts/SwarmControl.cs" />
|
<Compile Include="Assets/Scenes/Boids/Scripts/SwarmControl.cs" />
|
||||||
|
<Compile Include="Assets/NanoBrain/Perception.cs" />
|
||||||
<Compile Include="Assets/Scenes/Boids/Scripts/Boid.cs" />
|
<Compile Include="Assets/Scenes/Boids/Scripts/Boid.cs" />
|
||||||
<Compile Include="Assets/NanoBrain/Neuroid.cs" />
|
<Compile Include="Assets/NanoBrain/Neuroid.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@ -43,8 +43,9 @@ public class GraphEditorWindow : EditorWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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) && (neuroid.outputNeuroid == null ||
|
// Note: this does not yet work for multiple outputs yet (see the use of First())
|
||||||
(neuronVisited.Contains(neuroid.outputNeuroid) && neuroid.outputNeuroid.layerIx == layerIx - 1))) {
|
if (!neuronVisited.Contains(neuroid) && (neuroid.outputNeuroids.Count == 0 ||
|
||||||
|
(neuronVisited.Contains(neuroid.outputNeuroids.First()) && neuroid.outputNeuroids.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;
|
||||||
@ -54,7 +55,7 @@ public class GraphEditorWindow : EditorWindow {
|
|||||||
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}");
|
Debug.Log($"Layer {layerIx} neuron {neuroidIx} name {neuroid.name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,9 +111,9 @@ public class GraphEditorWindow : EditorWindow {
|
|||||||
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 = 200f / layerNeuroid.synapses.Count;
|
float inputSpacing = 200f / layerNeuroid.newSynapses.Count;
|
||||||
float inputMargin = 100 + inputSpacing / 2;
|
float inputMargin = 100 + inputSpacing / 2;
|
||||||
foreach (Synapse synapse in layerNeuroid.synapses.Values) {
|
foreach (Synapse synapse in layerNeuroid.newSynapses.Values) {
|
||||||
if (synapse.neuroid != null) {
|
if (synapse.neuroid != null) {
|
||||||
if (this.neuroidPositions.ContainsKey(synapse.neuroid)) {
|
if (this.neuroidPositions.ContainsKey(synapse.neuroid)) {
|
||||||
|
|
||||||
@ -144,7 +145,7 @@ public class GraphEditorWindow : EditorWindow {
|
|||||||
// Draw the tooltip
|
// Draw the tooltip
|
||||||
GUIContent tooltip = new(
|
GUIContent tooltip = new(
|
||||||
$"{neuroid.name}" +
|
$"{neuroid.name}" +
|
||||||
$"\nsynapse count {neuroid.synapses.Count}" +
|
$"\nsynapse count {neuroid.newSynapses.Count}" +
|
||||||
$"\nValue: {neuroid.outputValue}" +
|
$"\nValue: {neuroid.outputValue}" +
|
||||||
$"\nStale: {neuroid.stale}");
|
$"\nStale: {neuroid.stale}");
|
||||||
|
|
||||||
|
|||||||
@ -29,17 +29,16 @@ public class NeuroidNetwork {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class Neuroid {
|
public class Neuroid {
|
||||||
public int id;
|
//public int id;
|
||||||
public string name;
|
public string name;
|
||||||
|
|
||||||
public int layerIx;
|
public int layerIx;
|
||||||
public int stale = 0;
|
public int stale = 0;
|
||||||
|
|
||||||
public readonly Dictionary<int, Synapse> synapses = new();
|
public readonly Dictionary<Neuroid, Synapse> newSynapses = new();
|
||||||
|
|
||||||
public Vector3 outputValue;
|
public Vector3 outputValue;
|
||||||
public Neuroid outputNeuroid;
|
public HashSet<Neuroid> outputNeuroids = new();
|
||||||
public int outputNeurix;
|
|
||||||
|
|
||||||
public enum Mode {
|
public enum Mode {
|
||||||
Sum,
|
Sum,
|
||||||
@ -52,69 +51,95 @@ public class Neuroid {
|
|||||||
|
|
||||||
public Neuroid(NeuroidNetwork net) {
|
public Neuroid(NeuroidNetwork net) {
|
||||||
this.net = net;
|
this.net = net;
|
||||||
|
if (this.net != null)
|
||||||
this.net.neuroids.Add(this);
|
this.net.neuroids.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetOutputTo(Neuroid neuroid) {
|
public void AddSynapse(Neuroid input) {
|
||||||
this.outputNeuroid = neuroid;
|
input.AddReceiver(this);
|
||||||
// neuroid.inputNeuroids.Add(this);
|
this.newSynapses[input] = new(input, Vector3.zero, 1.0f);
|
||||||
this.outputNeurix = this.id;
|
}
|
||||||
|
|
||||||
|
public void AddReceiver(Neuroid receiver) {
|
||||||
|
this.outputNeuroids.Add(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetWeights() {
|
public void ResetWeights() {
|
||||||
foreach (Synapse synapse in synapses.Values)
|
foreach (Synapse synapse in this.newSynapses.Values)
|
||||||
synapse.weight = 1.0f;
|
synapse.weight = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetWeight(Neuroid input, float weight) {
|
public void SetWeight(Neuroid input, float weight) {
|
||||||
if (synapses.ContainsKey(input.id))
|
if (this.newSynapses.ContainsKey(input)) {
|
||||||
synapses[input.id] = new(input, synapses[input.id].value, weight);
|
this.newSynapses[input].weight = weight;
|
||||||
else
|
}
|
||||||
synapses[input.id] = new(input, Vector3.zero, weight);
|
else {
|
||||||
|
this.newSynapses[input] = new(input, Vector3.zero, weight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetInputFrom(Neuroid input, float weight = 1.0f) {
|
public void GetInputFrom(Neuroid input, float weight = 1.0f) {
|
||||||
input.id = this.synapses.Count;
|
input.AddReceiver(this);
|
||||||
input.SetOutputTo(this);
|
this.newSynapses[input] = new(input, Vector3.zero, weight);
|
||||||
synapses[input.id] = new(input, Vector3.zero, weight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetInput(int inputId, Vector3 value) {
|
public void SetInput(Neuroid input, Vector3 value) {
|
||||||
if (synapses.ContainsKey(inputId))
|
if (this.newSynapses.ContainsKey(input)) {
|
||||||
synapses[inputId].value = value;
|
Synapse synapse = this.newSynapses[input];
|
||||||
|
synapse.value = value;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
synapses[inputId] = new(null, value, 1.0f);
|
this.newSynapses[input] = new(null, value, 1.0f);
|
||||||
UpdateState();
|
UpdateState();
|
||||||
}
|
}
|
||||||
public void SetInput(int inputIx, Vector3 value, float weight) {
|
|
||||||
if (synapses.ContainsKey(inputIx)) {
|
public void SetInput(Neuroid input, Vector3 value, float weight) {
|
||||||
Synapse synapse = synapses[inputIx];
|
if (this.newSynapses.ContainsKey(input)) {
|
||||||
|
Synapse synapse = this.newSynapses[input];
|
||||||
synapse.value = value;
|
synapse.value = value;
|
||||||
synapse.weight = weight;
|
synapse.weight = weight;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
synapses[inputIx] = new(null, value, weight);
|
this.newSynapses[input] = new(null, value, weight);
|
||||||
UpdateState();
|
UpdateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateState() {
|
public readonly Dictionary<int, Neuroid> fakeNeuroids = new();
|
||||||
|
public void SetInput(int thingId, Vector3 value, float weight, NeuroidNetwork net) {
|
||||||
|
if (fakeNeuroids.ContainsKey(thingId)) {
|
||||||
|
Neuroid fakeInput = fakeNeuroids[thingId];
|
||||||
|
Synapse synapse = this.newSynapses[fakeInput];
|
||||||
|
synapse.value = value;
|
||||||
|
synapse.weight = weight;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fakeNeuroids[thingId] = new(net);
|
||||||
|
this.newSynapses[fakeNeuroids[thingId]] = new (null, value, weight);
|
||||||
|
}
|
||||||
|
UpdateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected virtual void UpdateState() {
|
||||||
Vector3 sum = Vector3.zero;
|
Vector3 sum = Vector3.zero;
|
||||||
foreach (Synapse synapse in synapses.Values)
|
foreach (Synapse synapse in this.newSynapses.Values)
|
||||||
sum += synapse.value * synapse.weight;
|
sum += synapse.value * synapse.weight;
|
||||||
|
|
||||||
this.outputValue = Activation(sum);
|
this.outputValue = Activation(sum);
|
||||||
this.outputNeuroid?.SetInput(this.outputNeurix, this.outputValue);
|
foreach (Neuroid neuroid in outputNeuroids) {
|
||||||
|
neuroid?.SetInput(this, this.outputValue);
|
||||||
|
}
|
||||||
this.stale = 0;
|
this.stale = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Activation(Vector3 sum) {
|
Vector3 Activation(Vector3 sum) {
|
||||||
if (synapses.Count == 0 && mode == Mode.Average)
|
if (this.newSynapses.Count == 0 && mode == Mode.Average)
|
||||||
Debug.LogWarning($"{this.id} {this.name} has zero synapses for average");
|
Debug.LogWarning($"{this.name} has zero synapses for average");
|
||||||
if (float.IsNaN(sum.magnitude))
|
if (float.IsNaN(sum.magnitude))
|
||||||
Debug.LogWarning($"{this.id} {this.name} sum is nan");
|
Debug.LogWarning($"{this.name} sum is nan");
|
||||||
return mode switch {
|
return mode switch {
|
||||||
Mode.Sum => sum,
|
Mode.Sum => sum,
|
||||||
Mode.Average => sum / synapses.Count,
|
Mode.Average => sum / this.newSynapses.Count,
|
||||||
_ => sum,
|
_ => sum,
|
||||||
};
|
};
|
||||||
//return sum; //(sum.magnitude > 0.5f) ? sum : Vector3.zero;
|
//return sum; //(sum.magnitude > 0.5f) ? sum : Vector3.zero;
|
||||||
|
|||||||
83
Assets/NanoBrain/Perception.cs
Normal file
83
Assets/NanoBrain/Perception.cs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class Perception {
|
||||||
|
public SensoryNeuroid[] sensoryNeuroids = new SensoryNeuroid[7];
|
||||||
|
//public Neuroid[] velocitySensors = new Neuroid[7];
|
||||||
|
public NeuroidNetwork neuroidNet { get; protected set; }
|
||||||
|
|
||||||
|
public HashSet<Neuroid> receivers { get; protected set; }
|
||||||
|
|
||||||
|
public Perception(NeuroidNetwork neuroidNet) {
|
||||||
|
this.neuroidNet = neuroidNet;
|
||||||
|
this.receivers = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void SendOutputTo(Neuroid receiver) {
|
||||||
|
// foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
|
||||||
|
// if (neuroid != null) {
|
||||||
|
// neuroid.AddReceiver(receiver);
|
||||||
|
// receiver.newSynapses[neuroid] = new (neuroid, Vector3.zero, 1.0f);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void SendPositions(Neuroid receiver) {
|
||||||
|
receivers.Add(receiver);
|
||||||
|
foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
|
||||||
|
if (neuroid != null) {
|
||||||
|
neuroid.AddReceiver(receiver);
|
||||||
|
receiver.newSynapses[neuroid] = new (neuroid, Vector3.zero, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void SendVelocities(Neuroid receiver) {
|
||||||
|
receivers.Add(receiver);
|
||||||
|
foreach (SensoryNeuroid neuroid in sensoryNeuroids) {
|
||||||
|
if (neuroid != null && neuroid.velocityNeuroid != null) {
|
||||||
|
neuroid.velocityNeuroid.AddReceiver(receiver);
|
||||||
|
receiver.newSynapses[neuroid] = new (neuroid, Vector3.zero, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ProcessStimulus(int thingId, Vector3 localPosition) {
|
||||||
|
int availableIx = -1;
|
||||||
|
SensoryNeuroid leastInterestingNeuroid = null;
|
||||||
|
for (int i = 0; i < sensoryNeuroids.Length; i++) {
|
||||||
|
if (sensoryNeuroids[i] == null || sensoryNeuroids[i].IsStale())
|
||||||
|
availableIx = i;
|
||||||
|
else if (sensoryNeuroids[i].receptor.thingId == thingId) {
|
||||||
|
sensoryNeuroids[i].receptor.position = localPosition;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sensoryNeuroids[i] != null) {
|
||||||
|
if (leastInterestingNeuroid == null || leastInterestingNeuroid.receptor.position.magnitude > sensoryNeuroids[i].receptor.position.magnitude)
|
||||||
|
leastInterestingNeuroid = sensoryNeuroids[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (availableIx != -1) {
|
||||||
|
if (sensoryNeuroids[availableIx] != null) {
|
||||||
|
// Debug.Log($"revived receptor {availableIx} for {thingId}");
|
||||||
|
sensoryNeuroids[availableIx].receptor.thingId = thingId;
|
||||||
|
sensoryNeuroids[availableIx].receptor.position = localPosition;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Debug.Log($"new receptor for {thingId}");
|
||||||
|
SensoryNeuroid neuroid = new(neuroidNet, thingId);
|
||||||
|
foreach (Neuroid receiver in receivers)
|
||||||
|
receiver.GetInputFrom(neuroid);
|
||||||
|
|
||||||
|
sensoryNeuroids[availableIx] = neuroid;
|
||||||
|
neuroid.receptor.position = localPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (leastInterestingNeuroid != null) {
|
||||||
|
//Debug.Log($"replaced receptor {leastInterestingNeuroid.thingId} for {thingId}");
|
||||||
|
leastInterestingNeuroid.receptor.thingId = thingId;
|
||||||
|
leastInterestingNeuroid.receptor.position = localPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Debug.LogWarning($"No available receptor for {id}");
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/NanoBrain/Perception.cs.meta
Normal file
2
Assets/NanoBrain/Perception.cs.meta
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 37d94d399d30e6eb996236adabad87ee
|
||||||
@ -1,32 +1,70 @@
|
|||||||
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class SensoryNeuroid : Neuroid {
|
||||||
|
// A neuroid which has no neurons as input
|
||||||
|
// But receives value from a receptor
|
||||||
|
public Receptor receptor;
|
||||||
|
public VelocityNeuroid velocityNeuroid;
|
||||||
|
|
||||||
|
public SensoryNeuroid(NeuroidNetwork net, int thingId) : base(net) {
|
||||||
|
this.name = "sensory neuroid";
|
||||||
|
this.receptor = new Receptor {
|
||||||
|
neuroid = this,
|
||||||
|
thingId = thingId
|
||||||
|
};
|
||||||
|
this.velocityNeuroid = new(net);
|
||||||
|
// The velocity neuroid received position data from this
|
||||||
|
this.AddReceiver(velocityNeuroid);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public class Receptor {
|
public class Receptor {
|
||||||
|
|
||||||
public SensoryNeuroid neuroid;
|
public SensoryNeuroid neuroid;
|
||||||
public void SetValue(Vector3 value) {
|
|
||||||
if (neuroid != null) {
|
public int thingId;
|
||||||
neuroid.SetInput(neuroid.id, value);
|
/// <summary>
|
||||||
}
|
/// Local position of the thing
|
||||||
}
|
/// </summary>
|
||||||
public Vector3 GetValue() {
|
public virtual Vector3 position {
|
||||||
|
get {
|
||||||
if (neuroid != null)
|
if (neuroid != null)
|
||||||
return neuroid.synapses[neuroid.id].value;
|
return neuroid.newSynapses[neuroid].value;
|
||||||
else
|
else
|
||||||
return Vector3.zero;
|
return Vector3.zero;
|
||||||
}
|
}
|
||||||
|
set {
|
||||||
|
if (neuroid != null)
|
||||||
|
neuroid.SetInput(neuroid, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class VelocityNeuroid : Neuroid {
|
||||||
|
// Would be best if this was received through a synapse via a loop....
|
||||||
|
private Vector3 lastPosition = Vector3.zero;
|
||||||
|
private float lastValueTime = 0;
|
||||||
|
|
||||||
public class SensoryNeuroid : Neuroid {
|
public VelocityNeuroid(NeuroidNetwork net) : base(net) {
|
||||||
public Receptor receptor;
|
|
||||||
public int thingId;
|
|
||||||
|
|
||||||
public SensoryNeuroid(NeuroidNetwork net, int id) : base(net) {
|
|
||||||
this.name = "sensory neuroid";
|
|
||||||
// this.id = id;
|
|
||||||
this.thingId = id;
|
|
||||||
this.receptor = new Receptor {
|
|
||||||
neuroid = this
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void UpdateState() {
|
||||||
|
// Assuming only one synapse for now....
|
||||||
|
Vector3 currentPosition = this.newSynapses.First().Value.value;
|
||||||
|
float currentValueTime = Time.time;
|
||||||
|
|
||||||
|
float deltaTime = currentValueTime - lastValueTime;
|
||||||
|
Vector3 translation = currentPosition - lastPosition;
|
||||||
|
Vector3 velocity = translation / deltaTime;
|
||||||
|
|
||||||
|
// No activation function...
|
||||||
|
this.outputValue = velocity;
|
||||||
|
foreach (Neuroid receiver in outputNeuroids)
|
||||||
|
receiver?.SetInput(this, this.outputValue);
|
||||||
|
this.stale = 0;
|
||||||
|
|
||||||
|
this.lastValueTime = Time.time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -378,7 +378,7 @@ MonoBehaviour:
|
|||||||
separationForce: 5
|
separationForce: 5
|
||||||
separationDistance: 0.3
|
separationDistance: 0.3
|
||||||
bodyForce: 20
|
bodyForce: 20
|
||||||
perceptionDistance: 2
|
perceptionDistance: 1
|
||||||
boundaryForce: 5
|
boundaryForce: 5
|
||||||
spaceSize: {x: 10, y: 10, z: 10}
|
spaceSize: {x: 10, y: 10, z: 10}
|
||||||
boundaryWidth: {x: 1, y: 1, z: 1}
|
boundaryWidth: {x: 1, y: 1, z: 1}
|
||||||
@ -394,7 +394,7 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: ec888ca5333d45a438f9f417fa5ce135, type: 3}
|
m_Script: {fileID: 11500000, guid: ec888ca5333d45a438f9f417fa5ce135, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier: Assembly-CSharp::SwarmSpawn
|
m_EditorClassIdentifier: Assembly-CSharp::SwarmSpawn
|
||||||
count: 1000
|
count: 5
|
||||||
boidPrefab: {fileID: 8702527964058765413, guid: f9c706268554ce449a8773675b2864b8, type: 3}
|
boidPrefab: {fileID: 8702527964058765413, guid: f9c706268554ce449a8773675b2864b8, type: 3}
|
||||||
spawnAreaSize: {x: 0.5, y: 0.5, z: 0.5}
|
spawnAreaSize: {x: 0.5, y: 0.5, z: 0.5}
|
||||||
minDelay: 0.05
|
minDelay: 0.05
|
||||||
|
|||||||
@ -19,7 +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 SensoryNeuroid[] neighbourSensor = new SensoryNeuroid[6];
|
||||||
|
public Perception perception;
|
||||||
|
|
||||||
public NeuroidNetwork neuroidNet = new();
|
public NeuroidNetwork neuroidNet = new();
|
||||||
public Neuroid bodyVector;
|
public Neuroid bodyVector;
|
||||||
@ -40,11 +41,14 @@ public class Boid : MonoBehaviour {
|
|||||||
|
|
||||||
bounds = new(sc.transform.position, sc.spaceSize - 2 * sc.boundaryWidth);
|
bounds = new(sc.transform.position, sc.spaceSize - 2 * sc.boundaryWidth);
|
||||||
|
|
||||||
|
perception = new Perception(neuroidNet);
|
||||||
//neighbourSensor = new(neuroidNet) { name = "Neighbour", id = 879 };
|
//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 };
|
||||||
|
perception.SendPositions(cohesion);
|
||||||
//cohesion.GetInputFrom(neighbourSensor);
|
//cohesion.GetInputFrom(neighbourSensor);
|
||||||
alignment = new(neuroidNet) { name = "Alignment", mode = Neuroid.Mode.Average };
|
alignment = new(neuroidNet) { name = "Alignment", mode = Neuroid.Mode.Average };
|
||||||
|
//perception.SendVelocities(alignment);
|
||||||
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 };
|
||||||
boundary = new(neuroidNet) { name = "Boundary", mode = Neuroid.Mode.Sum };
|
boundary = new(neuroidNet) { name = "Boundary", mode = Neuroid.Mode.Sum };
|
||||||
@ -78,15 +82,15 @@ public class Boid : MonoBehaviour {
|
|||||||
Vector3 localPosition = neighbour.transform.position - this.transform.position;
|
Vector3 localPosition = neighbour.transform.position - this.transform.position;
|
||||||
Vector3 relativeVelocity = neighbour.velocity - this.velocity;
|
Vector3 relativeVelocity = neighbour.velocity - this.velocity;
|
||||||
|
|
||||||
int id = neighbour.GetInstanceID();
|
int thingId = neighbour.GetInstanceID();
|
||||||
ProcessStimulus(id, localPosition);
|
perception.ProcessStimulus(thingId, 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(thingId, separationForce, sc.separationDistance, neuroidNet);
|
||||||
//cohesion.SetInput(id, localPosition, sc.cohesionForce);
|
//cohesion.SetInput(thingId, localPosition, sc.cohesionForce);
|
||||||
alignment.SetInput(id, relativeVelocity, sc.alignmentForce);
|
alignment.SetInput(thingId, relativeVelocity, sc.alignmentForce, neuroidNet);
|
||||||
neighbourCount++;
|
neighbourCount++;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -108,7 +112,7 @@ public class Boid : MonoBehaviour {
|
|||||||
Vector3 direction = (sc.transform.position - this.transform.position).normalized;
|
Vector3 direction = (sc.transform.position - this.transform.position).normalized;
|
||||||
outside = direction * magnitude;
|
outside = direction * magnitude;
|
||||||
|
|
||||||
boundary.SetInput(id, outside, sc.boundaryForce);
|
boundary.SetInput(id, outside, sc.boundaryForce, neuroidNet);
|
||||||
// Debug.Log($"boundary {this.transform.position} {outside} force = {outside * sc.boundaryForce}");
|
// Debug.Log($"boundary {this.transform.position} {outside} force = {outside * sc.boundaryForce}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +132,7 @@ public class Boid : MonoBehaviour {
|
|||||||
//Debug.Log($"neighbours: {neighbourCount} synapses: {cohesion.synapses.Count}");
|
//Debug.Log($"neighbours: {neighbourCount} synapses: {cohesion.synapses.Count}");
|
||||||
neuroidNet.Update();
|
neuroidNet.Update();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
Receptor GetReceptor(Neuroid perceptionNeuroid, int id) {
|
Receptor GetReceptor(Neuroid perceptionNeuroid, int id) {
|
||||||
int availableIx = -1;
|
int availableIx = -1;
|
||||||
for (int i = 0; i < neighbourSensor.Length; i++) {
|
for (int i = 0; i < neighbourSensor.Length; i++) {
|
||||||
@ -157,7 +161,7 @@ public class Boid : MonoBehaviour {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
void ProcessStimulus(int thingId, Vector3 value) {
|
void ProcessStimulus(int thingId, Vector3 value) {
|
||||||
int availableIx = -1;
|
int availableIx = -1;
|
||||||
SensoryNeuroid leastInterestingNeuroid = null;
|
SensoryNeuroid leastInterestingNeuroid = null;
|
||||||
@ -168,8 +172,6 @@ public class Boid : MonoBehaviour {
|
|||||||
neighbourSensor[i].receptor.SetValue(value);
|
neighbourSensor[i].receptor.SetValue(value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// if (leastInterestingIx == -1 || neighbourSensor[leastInterestingIx].receptor.GetValue().magnitude > neighbourSensor[i].receptor.GetValue().magnitude)
|
|
||||||
// leastInterestingIx = i;
|
|
||||||
if (neighbourSensor[i] != null) {
|
if (neighbourSensor[i] != null) {
|
||||||
if (leastInterestingNeuroid == null || leastInterestingNeuroid.receptor.GetValue().magnitude > neighbourSensor[i].receptor.GetValue().magnitude)
|
if (leastInterestingNeuroid == null || leastInterestingNeuroid.receptor.GetValue().magnitude > neighbourSensor[i].receptor.GetValue().magnitude)
|
||||||
leastInterestingNeuroid = neighbourSensor[i];
|
leastInterestingNeuroid = neighbourSensor[i];
|
||||||
@ -197,7 +199,7 @@ public class Boid : MonoBehaviour {
|
|||||||
|
|
||||||
//Debug.LogWarning($"No available receptor for {id}");
|
//Debug.LogWarning($"No available receptor for {id}");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
void OnDrawGizmosSelected() {
|
void OnDrawGizmosSelected() {
|
||||||
Gizmos.DrawWireSphere(transform.position, sc.perceptionDistance);
|
Gizmos.DrawWireSphere(transform.position, sc.perceptionDistance);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user