source: cpp/frams/genetics/geneprops.cpp @ 1304

Last change on this file since 1304 was 1260, checked in by Maciej Komosinski, 18 months ago

Cosmetic

File size: 8.6 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include "geneprops.h"
6#include <algorithm>
7
8GeneProps GeneProps::standard_values;
9
10GeneProps::GeneProps()
11{
12        Part_MinMaxDef default_part = Model::getDefPart();
13        Joint default_joint = Model::getDefJoint();
14
15        length = 1.0;
16        weight = 1.0;
17        friction = default_part.friction;
18        curvedness = 0.0;
19        twist = 0.0;
20        energy = 1.0;
21
22        // before 2023-05, the four fields below were aggregated and normalized using normalizeBiol4(), but this normalization only worked for f1 and f4 - other genetic encodings do not perform such normalization. If at all, this should be handled by the expdef depending on the goal of the experiment (e.g., to encourage specialization).
23        muscle_power = 0.25; // "biological" property, same as findNeuroClass("BendMuscle or RotMuscle")->paraminterface->getDoubleById("power")
24        assimilation = default_part.assim; // "biological" property
25        stamina = default_joint.stamina; // "biological" property
26        ingestion = default_part.ingest; // "biological" property
27
28        muscle_bend_range = 1.0; // same as findNeuroClass("BendMuscle")->paraminterface->getDoubleById("range")
29        muscle_reset_range = true;
30
31        cred = default_part.vcolor.x;
32        cgreen = default_part.vcolor.y;
33        cblue = default_part.vcolor.z;
34}
35
36void GeneProps::normalizeBiol4()
37{
38        // make them sum to 1
39        double sum = muscle_power + assimilation + stamina + ingestion;
40        if (sum == 0)
41        {
42                muscle_power = assimilation = stamina = ingestion = 0.25;
43        }
44        else
45        {
46                muscle_power /= sum;
47                assimilation /= sum;
48                stamina /= sum;
49                ingestion /= sum;
50        }
51}
52
53int GeneProps::executeModifier(char modif, GenePropsOps* ops)
54{
55        if (ops == NULL)
56                ops = getDefaultOps();
57
58#define APPLY(name) ops->name->apply(name, modif)
59#define APPLY_AND_MAYBE_NORMALIZEBIOL4(name) {APPLY(name); if (ops->use_normalizebiol4) normalizeBiol4();}
60
61        switch (toupper(modif))
62        {
63        case 'L': APPLY(length);
64                length = std::min(length, Model::getMaxJoint().d.x); break;
65                break;
66
67        case 'l': APPLY(length);
68                length = std::max(length, Model::getMinJoint().d.x); break;
69                break;
70
71        case 'W': APPLY(weight); break;
72        case 'F': APPLY(friction); break;
73        case 'C': APPLY(curvedness); break;
74        case 'Q': APPLY(twist); break;
75        case 'E': APPLY(energy); break;
76
77        case 'A': APPLY_AND_MAYBE_NORMALIZEBIOL4(assimilation); break;
78        case 'I': APPLY_AND_MAYBE_NORMALIZEBIOL4(ingestion); break;
79        case 'S': APPLY_AND_MAYBE_NORMALIZEBIOL4(stamina); break;
80        case 'M': APPLY_AND_MAYBE_NORMALIZEBIOL4(muscle_power); break;
81
82        case 'D': APPLY(cred); break;
83        case 'G': APPLY(cgreen); break;
84        case 'B': APPLY(cblue); break;
85
86        default: return -1;
87        }
88        return 0;
89
90#undef APPLY
91#undef APPLY_AND_MAYBE_NORMALIZEBIOL4
92}
93
94void GeneProps::propagateAlong(bool use_f1_muscle_reset_range, GenePropsOps* ops)
95{
96        length = 0.5 * length + 0.5 * standard_values.length;
97        weight += (standard_values.weight - weight) * 0.5;
98        friction = 0.8 * friction + 0.2 * standard_values.friction;
99        curvedness = 0.66 * curvedness;
100        twist = 0.66 * twist;
101
102        assimilation = 0.8 * assimilation + 0.2 * standard_values.assimilation;
103        ingestion = 0.8 * ingestion + 0.2 * standard_values.ingestion;
104        stamina = 0.8 * stamina + 0.2 * standard_values.stamina;
105        muscle_power = 0.8 * muscle_power + 0.2 * standard_values.muscle_power;
106
107        if (ops == NULL)
108                ops = getDefaultOps();
109        if (ops->use_normalizebiol4) normalizeBiol4();
110
111        if (use_f1_muscle_reset_range)
112        {
113                if (muscle_reset_range) muscle_bend_range = 1.0; else muscle_reset_range = true;
114        }
115}
116
117////////////////////////////////////////////////////
118
119void GenePropsOp::apply(double &value, char modif) const
120{
121        if (isupper(modif))
122                value = increase(value);
123        else
124                value = decrease(value);
125}
126
127double GenePropsOp_Legacy::increase(double value) const
128{
129        return value + (maxvalue - value) * change;
130}
131
132double GenePropsOp_Legacy::decrease(double value) const
133{
134        return value + (minvalue - value) * revchange;
135}
136
137GenePropsOp_Legacy::GenePropsOp_Legacy(double minvalue, double maxvalue, double defvalue, double change, double revchange)
138{
139        this->minvalue = minvalue;
140        this->maxvalue = maxvalue;
141        this->defvalue = defvalue;
142        this->change = change;
143        this->revchange = (revchange < 0) ? change : revchange;
144}
145
146GenePropsOp_Exponential::GenePropsOp_Exponential(double minvalue, double maxvalue, double defvalue, double change)
147        :GenePropsOp_NormalizedAndScaled(change)
148{
149        double mid = (maxvalue + minvalue) / 2;
150        if (fabs(mid - defvalue) < 0.01)
151        {
152                linear = true;
153                a = (maxvalue - minvalue) / 2;
154                b = defvalue;
155        }
156        else
157        {
158                linear = false;
159                a = -(maxvalue - defvalue) / (minvalue - defvalue);
160                b = (minvalue * minvalue - 2 * defvalue * minvalue + defvalue * defvalue) / (minvalue + maxvalue - 2 * defvalue);
161                c = (maxvalue * minvalue - defvalue * defvalue) / (minvalue + maxvalue - 2 * defvalue);
162                log_a = log(a);
163        }
164}
165
166double GenePropsOp_Exponential::scale(double value) const
167{
168        if (linear)
169                return a * value + b;
170        else
171                return pow(a, (value + 1)) * b + c;
172}
173
174double GenePropsOp_Exponential::scaleInv(double value) const
175{
176        if (linear)
177                return (value - b) / a;
178        else
179                return -(log_a - log(value / b - c / b)) / log_a;
180}
181
182////////////////////////////////////////////////////////////////////
183
184
185GenePropsOps::~GenePropsOps()
186{
187        delete length;
188        delete curvedness;
189        delete weight;
190        delete friction;
191        delete muscle_power;
192        delete assimilation;
193        delete stamina;
194        delete ingestion;
195        delete twist;
196        delete energy;
197        delete cred;
198        delete cgreen;
199        delete cblue;
200}
201
202GenePropsOps_Legacy::GenePropsOps_Legacy()
203{
204        use_normalizebiol4 = true;
205
206        length = new GenePropsOp_Legacy(0.33, 2.0, GeneProps::standard_values.length, 0.3);
207        weight = new GenePropsOp_Legacy(0.5, 2.0, GeneProps::standard_values.weight, 0.3);
208        friction = new GenePropsOp_Legacy(0, 4.0, GeneProps::standard_values.friction, 0.2);
209        curvedness = new GenePropsOp_Legacy(-2, 2, GeneProps::standard_values.curvedness, 0.25);
210        twist = new GenePropsOp_Legacy(-M_PI_2, M_PI_2, GeneProps::standard_values.twist, 0.3);
211        energy = new GenePropsOp_Legacy(0, 10, GeneProps::standard_values.energy, 0.1);
212
213        assimilation = new GenePropsOp_Legacy(0, 1, GeneProps::standard_values.assimilation, 0.8, 0.4);
214        ingestion = new GenePropsOp_Legacy(0, 1, GeneProps::standard_values.ingestion, 0.8, 0.4);
215        stamina = new GenePropsOp_Legacy(0, 1, GeneProps::standard_values.stamina, 0.8, 0.4);
216        muscle_power = new GenePropsOp_Legacy(0, 1, GeneProps::standard_values.muscle_power, 0.8, 0.4);
217
218        cred = new GenePropsOp_Legacy(0, 1, GeneProps::standard_values.cred, 0.25);
219        cgreen = new GenePropsOp_Legacy(0, 1, GeneProps::standard_values.cgreen, 0.25);
220        cblue = new GenePropsOp_Legacy(0, 1, GeneProps::standard_values.cblue, 0.25);
221}
222
223GenePropsOps_AllChange05::GenePropsOps_AllChange05()
224{
225        use_normalizebiol4 = false;
226
227        constexpr float CHANGE = 0.5;
228        auto fields = { length,curvedness,weight,friction,muscle_power,assimilation,stamina,ingestion,twist,energy,cred,cgreen,cblue };
229        for (auto f : fields)
230        {
231                auto f_gpo = dynamic_cast<GenePropsOp_Legacy*>(f);
232                if (f_gpo)
233                        f_gpo->change = f_gpo->revchange = CHANGE;
234        }
235
236        delete curvedness;
237        curvedness = new GenePropsOp_Legacy(-M_PI_2, M_PI_2, GeneProps::standard_values.curvedness, CHANGE);
238}
239
240GenePropsOps_Exponential::GenePropsOps_Exponential()
241{
242        length = new GenePropsOp_Exponential(0.33, 2.0, GeneProps::standard_values.length);
243        weight = new GenePropsOp_Exponential(0.5, 2.0, GeneProps::standard_values.weight);
244        friction = new GenePropsOp_Exponential(0, 4.0, GeneProps::standard_values.friction);
245        curvedness = new GenePropsOp_Exponential(-2, 2, GeneProps::standard_values.curvedness);
246        twist = new GenePropsOp_Exponential(-M_PI_2, M_PI_2, GeneProps::standard_values.twist);
247        energy = new GenePropsOp_Exponential(0, 10, GeneProps::standard_values.energy);
248
249        assimilation = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.assimilation);
250        ingestion = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.ingestion);
251        stamina = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.stamina);
252        muscle_power = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.muscle_power);
253
254        cred = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.cred);
255        cgreen = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.cgreen);
256        cblue = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.cblue);
257}
258
259GenePropsOps* GeneProps::getAllChange05Ops()
260{
261        static GenePropsOps_AllChange05 ops;
262        return &ops;
263}
264
265GenePropsOps* GeneProps::getLegacyOps()
266{
267        static GenePropsOps_Legacy ops;
268        return &ops;
269}
270
271static GenePropsOps* default_ops = NULL;
272
273GenePropsOps* GeneProps::getDefaultOps()
274{
275        if (!default_ops)
276                default_ops = getAllChange05Ops();
277        return default_ops;
278}
279
280void GeneProps::setDefaultOps(GenePropsOps* ops)
281{
282        default_ops = ops;
283}
Note: See TracBrowser for help on using the repository browser.