Changeset 721 for cpp/frams/neuro


Ignore:
Timestamp:
01/14/18 11:25:02 (6 years ago)
Author:
Maciej Komosinski
Message:

Code formatting

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/neuro/neuroimpl.h

    r646 r721  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    2323{
    2424public:
    25 NeuroNetConfig(NeuroFactory *fac);
    26 
    27 Param par;
    28 double randominit;
    29 double nnoise;
    30 double touchrange;
    31 
    32 NeuroFactory *factory;
    33 //static NeuroNetConfig& getGlobalConfig();
     25        NeuroNetConfig(NeuroFactory *fac);
     26
     27        Param par;
     28        double randominit;
     29        double nnoise;
     30        double touchrange;
     31
     32        NeuroFactory *factory;
     33        //static NeuroNetConfig& getGlobalConfig();
    3434};
    3535
    3636#ifdef NEURO_SIGNALS
    37 class NeuroSignals: public SignalSet
     37class NeuroSignals : public SignalSet
    3838{
    39   protected:
    40 Creature *cr;
    41 NeuroImpl *owner;
    42 Creature *getCreature();
    43   public:
    44 
    45 NeuroSignals(NeuroImpl *n):cr(0),owner(n) {}
     39protected:
     40        Creature *cr;
     41        NeuroImpl *owner;
     42        Creature *getCreature();
     43public:
     44
     45        NeuroSignals(NeuroImpl *n) :cr(0), owner(n) {}
    4646
    4747#define STATRICKCLASS NeuroSignals
    48 PARAMPROCDEF(p_add);
    49 PARAMPROCDEF(p_get);
    50 PARAMGETDEF(size);
    51 PARAMPROCDEF(p_receive);
    52 PARAMPROCDEF(p_receiveSet);
    53 PARAMPROCDEF(p_receiveFilter);
    54 PARAMPROCDEF(p_receiveSingle);
     48        PARAMPROCDEF(p_add);
     49        PARAMPROCDEF(p_get);
     50        PARAMGETDEF(size);
     51        PARAMPROCDEF(p_receive);
     52        PARAMPROCDEF(p_receiveSet);
     53        PARAMPROCDEF(p_receiveFilter);
     54        PARAMPROCDEF(p_receiveSingle);
    5555#undef STATRICKCLASS
    5656
    57 static Param& getStaticParam();
     57        static Param& getStaticParam();
    5858};
    5959#endif
     
    6262class NeuroNetImpl
    6363{
    64 CallbackNode *cnode;
    65 Model &mod;
    66 SList neurons[4];
    67 NeuroNetConfig& config;
    68 int isbuilt,errorcount;
    69 STCALLBACKDEFC(NeuroNetImpl,destroyNN);
    70 int minorder,maxorder;
    71 
    72   public:
    73 #ifdef NEURO_SIGNALS
    74 ChannelSpace *channels;
    75 #endif
    76 static int mytags_id;
    77 static double getStateFromNeuro(Neuro *n);
    78 int getErrorCount() {return errorcount;}
    79 NeuroNetConfig &getConfig() {return config;}
    80 NeuroNetImpl(Model& model, NeuroNetConfig& conf
    81 #ifdef NEURO_SIGNALS
    82 , ChannelSpace *ch=0
    83 #endif
    84 );
    85 ~NeuroNetImpl();
    86 void simulateNeuroNet();
    87 void simulateNeuroPhysics();
    88 
    89 static NeuroImpl *getImpl(Neuro* n) {return (NeuroImpl*)n->userdata[mytags_id];}
     64        CallbackNode *cnode;
     65        Model &mod;
     66        SList neurons[4];
     67        NeuroNetConfig& config;
     68        int isbuilt, errorcount;
     69        STCALLBACKDEFC(NeuroNetImpl, destroyNN);
     70        int minorder, maxorder;
     71
     72public:
     73#ifdef NEURO_SIGNALS
     74        ChannelSpace *channels;
     75#endif
     76        static int mytags_id;
     77        static double getStateFromNeuro(Neuro *n);
     78        int getErrorCount() { return errorcount; }
     79        NeuroNetConfig &getConfig() { return config; }
     80        NeuroNetImpl(Model& model, NeuroNetConfig& conf
     81#ifdef NEURO_SIGNALS
     82                , ChannelSpace *ch = 0
     83#endif
     84                );
     85        ~NeuroNetImpl();
     86        void simulateNeuroNet();
     87        void simulateNeuroPhysics();
     88
     89        static NeuroImpl *getImpl(Neuro* n) { return (NeuroImpl*)n->userdata[mytags_id]; }
    9090};
    9191
     
    9595   (Neuro::state) in each simulation step.
    9696
    97 SUBCLASSING TUTORIAL
    98 ====================
    99 
    100 1.Derive your custom neuron from NeuroImpl class. The name must be prefixed with NI_
    101 
    102 class NI_MyNeuron: public NeuroImpl
    103 { ... };
    104 
    105 2.Public parameters
    106 Create any number of public fields, they will be adjustable from the genotype level.
    107 3 datatypes are supported: long, double and SString
    108 
    109 public:
    110   paInt intParameter;
    111   double fpParameter;
    112   SString txtParameter;
    113 
    114 
    115 3.Required method: "instantiator".
    116 It is always the same, just create a new instance of your neuron.
    117 public:
    118   NeuroImpl* makeNew() { return new NI_MyNeuron(); };
    119 
    120 
    121 4.Required method: default constructor
    122 Set the "paramentries" variable if you need public parameters in your neuron.
    123 NI_..._tab is created automatically and should be declared as: extern ParamEntry NI_..._tab[];
    124 At this stage the parameter values are not yet available.
    125 
    126 public:
    127  NI_MyNeuron() // no parameters!
    128  {
    129  paramentries=NI_MyNeuron_tab;
    130  // you add here: some general initialization
    131  }
    132 
    133 
    134 5.Optional method: initialization
    135 This method is called once before the neuron is actually used in the simulation.
    136 The parameter values are already initialized (according to the genotype) and the neuron is bound to the creature (i.e. this->neuro is valid).
    137 Return 0 if the neuron cannot be initialized.
    138 
    139 int lateinit()
    140  {
    141  // you add here: initialization using full neuron context
    142  // example: if (!neuro->joint) return 0; //this neuron must be attached to joint
    143  return 1;//OK
    144  }
    145 
    146 
    147 6.Required method: simulation step
    148 If it has output: calculate the next neuron state and call setState()
    149 If it is an effector: do anything else
    150 
    151 void go()
    152  {
    153  // you add here: things called every simulation step
    154  }
    155 
    156 Note: You can make your neuron fire before or after "regular" neurons by changing its "simorder" property (during initialization). The default value is 1, whereas receptors have simorder=0 and effectors have simorder=2.
    157 
    158 
    159 7.Neuron definition
    160 In order to incorporate the new neuron into Framsticks you need to provide some additional information (to be added to "f0.def" file).
    161 
    162 NEUROCLASS(MyNeuron,MN,This is the name,`Neuron description',-1,1,0)
    163 NEUROPROP(int,0,0,name of the int,d,,,,intParameter)
    164 NEUROPROP(fp,0,0,name of the floating point,f,,,,fpParameter)
    165 NEUROPROP(txt,0,0,name of the text,s,,,,txtParameter)
    166 ENDNEUROCLASS
    167 
    168 NEUROCLASS:
    169 - MyNeuron: neuron class name (without the NI_ prefix)
    170 - MN: neuron symbol (used in genotypes)
    171 - full name and description
    172 - -1: preferred number of inputs (special case: -1=any)
    173 - 1: provides output: 1=yes/0=no
    174 - 0: preferred location: 0=none, 1=part, 2=joint
    175 
    176 NEUROPROP:
    177 - int/fp/txt: parameter names as visible in genotypes and scripting
    178 - "name of the ...": descriptive name
    179 - d/f/s: type (int/floating point/string)
    180 - intParameter/fpParameter/txtParameter: C++ field names
    181 
    182    
    183  */
     97   SUBCLASSING TUTORIAL
     98   ====================
     99
     100   1.Derive your custom neuron from NeuroImpl class. The name must be prefixed with NI_
     101
     102   class NI_MyNeuron: public NeuroImpl
     103   { ... };
     104
     105   2.Public parameters
     106   Create any number of public fields, they will be adjustable from the genotype level.
     107   3 datatypes are supported: long, double and SString
     108
     109   public:
     110   paInt intParameter;
     111   double fpParameter;
     112   SString txtParameter;
     113
     114
     115   3.Required method: "instantiator".
     116   It is always the same, just create a new instance of your neuron.
     117   public:
     118   NeuroImpl* makeNew() { return new NI_MyNeuron(); };
     119
     120
     121   4.Required method: default constructor
     122   Set the "paramentries" variable if you need public parameters in your neuron.
     123   NI_..._tab is created automatically and should be declared as: extern ParamEntry NI_..._tab[];
     124   At this stage the parameter values are not yet available.
     125
     126   public:
     127   NI_MyNeuron() // no parameters!
     128   {
     129   paramentries=NI_MyNeuron_tab;
     130   // you add here: some general initialization
     131   }
     132
     133
     134   5.Optional method: initialization
     135   This method is called once before the neuron is actually used in the simulation.
     136   The parameter values are already initialized (according to the genotype) and the neuron is bound to the creature (i.e. this->neuro is valid).
     137   Return 0 if the neuron cannot be initialized.
     138
     139   int lateinit()
     140   {
     141   // you add here: initialization using full neuron context
     142   // example: if (!neuro->joint) return 0; //this neuron must be attached to joint
     143   return 1;//OK
     144   }
     145
     146
     147   6.Required method: simulation step
     148   If it has output: calculate the next neuron state and call setState()
     149   If it is an effector: do anything else
     150
     151   void go()
     152   {
     153   // you add here: things called every simulation step
     154   }
     155
     156   Note: You can make your neuron fire before or after "regular" neurons by changing its "simorder" property (during initialization). The default value is 1, whereas receptors have simorder=0 and effectors have simorder=2.
     157
     158
     159   7.Neuron definition
     160   In order to incorporate the new neuron into Framsticks you need to provide some additional information (to be added to "f0.def" file).
     161
     162   NEUROCLASS(MyNeuron,MN,This is the name,`Neuron description',-1,1,0)
     163   NEUROPROP(int,0,0,name of the int,d,,,,intParameter)
     164   NEUROPROP(fp,0,0,name of the floating point,f,,,,fpParameter)
     165   NEUROPROP(txt,0,0,name of the text,s,,,,txtParameter)
     166   ENDNEUROCLASS
     167
     168   NEUROCLASS:
     169   - MyNeuron: neuron class name (without the NI_ prefix)
     170   - MN: neuron symbol (used in genotypes)
     171   - full name and description
     172   - -1: preferred number of inputs (special case: -1=any)
     173   - 1: provides output: 1=yes/0=no
     174   - 0: preferred location: 0=none, 1=part, 2=joint
     175
     176   NEUROPROP:
     177   - int/fp/txt: parameter names as visible in genotypes and scripting
     178   - "name of the ...": descriptive name
     179   - d/f/s: type (int/floating point/string)
     180   - intParameter/fpParameter/txtParameter: C++ field names
     181
     182
     183   */
    184184class NeuroImpl
    185185{
    186186protected:
    187 int simorder;
    188 int channels;
    189 SListTempl<double> chstate;
    190 SListTempl<double> chnewstate;
    191 Param *fields_param;
    192 ExtObject *fields_object;
     187        int simorder;
     188        int channels;
     189        SListTempl<double> chstate;
     190        SListTempl<double> chnewstate;
     191        Param *fields_param;
     192        ExtObject *fields_object;
    193193public:
    194 static const int ENDDRAWING;
    195 static const int MAXDRAWINGXY;
    196 
    197 enum NeuroImplStats { BeforeInit=0, InitError=1, InitOk=2 };
    198 NeuroImplStats status;
    199 /** originating neuron object (from the model) */
    200 Neuro *neuro;
    201 NeuroClass *neuroclass;
    202 /** don't access directly */
    203 double newstate;
    204 NeuroNetImpl *owner;
    205 /** will be used by readParam() method, if not null  */
    206 ParamEntry *paramentries; // no extra properties if ==0
    207 
    208 #ifdef NEURO_SIGNALS
    209 NeuroSignals sigs;
    210 ExtObject sigs_obj;
    211 #endif
    212 
    213 /** "virtual constructor" - NeuroFactory uses this method to create the proper implementation object.
    214     subclasses must return new object here. */
    215 virtual NeuroImpl* makeNew() {return 0;} //
    216 /** read additional properties from "moredata" field of the originating Neuro */
    217 void readParam();
    218 /** called when all other neuro objects were already created and "moredata" transferred to
    219     object fields.
    220     useful for initialization that cannot be performed in the constructor.
    221     @return 1=ok  0=failure
    222 */
    223 virtual int lateinit() {return 1;}
    224 /** calculate 'newstate - implementation dependent */
    225 virtual void go(){}
    226 /** for neurons doing some physical actions (called each simulation step when nnspeed!=1.0) */
    227 virtual void goPhysics(){}
    228 
    229 int getSimOrder() {return simorder;}
    230 virtual int getNeedPhysics() {return 0;}
    231 
    232 void setChannelCount(int c);
    233 int getChannelCount() {return channels;}
    234 
    235 int getInputCount() {return neuro->getInputCount();}
    236 int getInputChannelCount(int i);
    237 double getInputState(int i,int channel=0);
    238 double getWeightedInputState(int i,int channel=0);
    239 double getInputSum(int startwith=0);
    240 double getWeightedInputSum(int startwith=0);
    241 double getInputWeight(int i) {return neuro->getInputWeight(i);}
    242 void setState(double st,int channel);
    243 void setState(double st) {validateNeuroState(st); newstate=st;}
    244 double getState(int channel);
    245 double getState() {return neuro->state;}
    246 
    247 virtual int getDrawingCount() {return 0;}
    248 virtual int* getDrawing(int i) {return 0;}
    249 
    250 /** is this implementation current? script neurons retain their original implementation when reloading *.neuro */
    251 virtual bool isCurrent() {return true;}
    252 
    253 void commit();
    254 void validateNeuroState(double& st) {if (st<=-1e10) st=-1e10; else if (st>1e10) st=1e10;}
    255 
    256 NeuroImpl():simorder(1),channels(1),fields_param(0),fields_object(0),status(BeforeInit),neuro(0),newstate(0),owner(0),paramentries(0)
    257 #ifdef NEURO_SIGNALS
    258 ,sigs(this),sigs_obj(&NeuroSignals::getStaticParam(),&sigs)
    259 #endif
    260  {}
    261 virtual ~NeuroImpl();
    262 virtual void createFieldsObject();
    263 
    264 /** usually == "newstate" but will obey the "hold state" */
    265 double getNewState(int channel=0);
    266 
    267 /** don't use! */
    268 void setCurrentState(double st,int channel=0);
    269 
    270 bool getPosition(Pt3D &pos);
    271 Creature* getCreature();
     194        static const int ENDDRAWING;
     195        static const int MAXDRAWINGXY;
     196
     197        enum NeuroImplStats { BeforeInit = 0, InitError = 1, InitOk = 2 };
     198        NeuroImplStats status;
     199        /** originating neuron object (from the model) */
     200        Neuro *neuro;
     201        NeuroClass *neuroclass;
     202        /** don't access directly */
     203        double newstate;
     204        NeuroNetImpl *owner;
     205        /** will be used by readParam() method, if not null  */
     206        ParamEntry *paramentries; // no extra properties if ==0
     207
     208#ifdef NEURO_SIGNALS
     209        NeuroSignals sigs;
     210        ExtObject sigs_obj;
     211#endif
     212
     213        /** "virtual constructor" - NeuroFactory uses this method to create the proper implementation object.
     214                subclasses must return new object here. */
     215        virtual NeuroImpl* makeNew() { return 0; } //
     216        /** read additional properties from "moredata" field of the originating Neuro */
     217        void readParam();
     218        /** called when all other neuro objects were already created and "moredata" transferred to
     219                object fields.
     220                useful for initialization that cannot be performed in the constructor.
     221                @return 1=ok  0=failure
     222                */
     223        virtual int lateinit() { return 1; }
     224        /** calculate 'newstate - implementation dependent */
     225        virtual void go(){}
     226        /** for neurons doing some physical actions (called each simulation step when nnspeed!=1.0) */
     227        virtual void goPhysics(){}
     228
     229        int getSimOrder() { return simorder; }
     230        virtual int getNeedPhysics() { return 0; }
     231
     232        void setChannelCount(int c);
     233        int getChannelCount() { return channels; }
     234
     235        int getInputCount() { return neuro->getInputCount(); }
     236        int getInputChannelCount(int i);
     237        double getInputState(int i, int channel = 0);
     238        double getWeightedInputState(int i, int channel = 0);
     239        double getInputSum(int startwith = 0);
     240        double getWeightedInputSum(int startwith = 0);
     241        double getInputWeight(int i) { return neuro->getInputWeight(i); }
     242        void setState(double st, int channel);
     243        void setState(double st) { validateNeuroState(st); newstate = st; }
     244        double getState(int channel);
     245        double getState() { return neuro->state; }
     246
     247        virtual int getDrawingCount() { return 0; }
     248        virtual int* getDrawing(int i) { return 0; }
     249
     250        /** is this implementation current? script neurons retain their original implementation when reloading *.neuro */
     251        virtual bool isCurrent() { return true; }
     252
     253        void commit();
     254        void validateNeuroState(double& st) { if (st <= -1e10) st = -1e10; else if (st > 1e10) st = 1e10; }
     255
     256        NeuroImpl() :simorder(1), channels(1), fields_param(0), fields_object(0), status(BeforeInit), neuro(0), newstate(0), owner(0), paramentries(0)
     257#ifdef NEURO_SIGNALS
     258                , sigs(this), sigs_obj(&NeuroSignals::getStaticParam(), &sigs)
     259#endif
     260        {}
     261        virtual ~NeuroImpl();
     262        virtual void createFieldsObject();
     263
     264        /** usually == "newstate" but will obey the "hold state" */
     265        double getNewState(int channel = 0);
     266
     267        /** don't use! */
     268        void setCurrentState(double st, int channel = 0);
     269
     270        bool getPosition(Pt3D &pos);
     271        Creature* getCreature();
    272272
    273273#define STATRICKCLASS NeuroImpl
    274 PARAMGETDEF(count) {arg1->setInt(getInputCount());}
    275 PARAMPROCDEF(p_get) {arg2->setDouble(getInputState(arg1->getInt()));}
    276 PARAMPROCDEF(p_getweight) {arg2->setDouble(getInputWeight(arg1->getInt()));}
    277 PARAMPROCDEF(p_getw) {arg2->setDouble(getWeightedInputState(arg1->getInt()));}
    278 PARAMPROCDEF(p_getsum) {arg2->setDouble(getInputSum(arg1->getInt()));}
    279 PARAMPROCDEF(p_getwsum) {arg2->setDouble(getWeightedInputSum(arg1->getInt()));}
    280 PARAMGETDEF(sum) {arg1->setDouble(getInputSum(0));}
    281 PARAMGETDEF(wsum) {arg1->setDouble(getWeightedInputSum(0));}
    282 PARAMPROCDEF(p_getchancount) {arg2->setInt(getInputChannelCount(arg1->getInt()));}
    283 PARAMPROCDEF(p_getchan) {arg2->setDouble(getInputState(arg1[1].getInt(),arg1[0].getInt()));}
    284 PARAMPROCDEF(p_getwchan) {arg2->setDouble(getWeightedInputState(arg1[1].getInt(),arg1[0].getInt()));}
    285 PARAMGETDEF(state) {arg1->setDouble(getState());}
    286 PARAMSETDEF(state) {setState(arg1->getDouble()); return 0;}
    287 PARAMGETDEF(cstate) {arg1->setDouble(neuro->state);}
    288 PARAMSETDEF(cstate) {setCurrentState(arg1->getDouble()); return 0;}
    289 PARAMGETDEF(hold) {arg1->setInt((neuro->flags&(Neuro::HoldState))?1:0);}
    290 PARAMSETDEF(hold) {neuro->flags=(neuro->flags&~Neuro::HoldState)|(arg1->getInt()?Neuro::HoldState:0); return 0;}
    291 PARAMGETDEF(channels) {arg1->setInt(getChannelCount());}
    292 PARAMSETDEF(channels) {setChannelCount(arg1->getInt()); return 0;}
    293 PARAMPROCDEF(p_getstate) {arg2->setDouble(getState(arg1->getInt()));}
    294 PARAMPROCDEF(p_setstate) {setState(arg1[0].getDouble(),arg1[1].getInt());}
    295 PARAMPROCDEF(p_setcstate) {setCurrentState(arg1[0].getDouble(),arg1[1].getInt());}
    296 PARAMGETDEF(creature);
    297 PARAMGETDEF(part);
    298 PARAMGETDEF(joint);
    299 PARAMGETDEF(position_x);
    300 PARAMGETDEF(position_y);
    301 PARAMGETDEF(position_z);
    302 PARAMGETDEF(fields);
    303 PARAMGETDEF(neurodef);
    304 PARAMGETDEF(classObject);
     274        PARAMGETDEF(count) { arg1->setInt(getInputCount()); }
     275        PARAMPROCDEF(p_get) { arg2->setDouble(getInputState(arg1->getInt())); }
     276        PARAMPROCDEF(p_getweight) { arg2->setDouble(getInputWeight(arg1->getInt())); }
     277        PARAMPROCDEF(p_getw) { arg2->setDouble(getWeightedInputState(arg1->getInt())); }
     278        PARAMPROCDEF(p_getsum) { arg2->setDouble(getInputSum(arg1->getInt())); }
     279        PARAMPROCDEF(p_getwsum) { arg2->setDouble(getWeightedInputSum(arg1->getInt())); }
     280        PARAMGETDEF(sum) { arg1->setDouble(getInputSum(0)); }
     281        PARAMGETDEF(wsum) { arg1->setDouble(getWeightedInputSum(0)); }
     282        PARAMPROCDEF(p_getchancount) { arg2->setInt(getInputChannelCount(arg1->getInt())); }
     283        PARAMPROCDEF(p_getchan) { arg2->setDouble(getInputState(arg1[1].getInt(), arg1[0].getInt())); }
     284        PARAMPROCDEF(p_getwchan) { arg2->setDouble(getWeightedInputState(arg1[1].getInt(), arg1[0].getInt())); }
     285        PARAMGETDEF(state) { arg1->setDouble(getState()); }
     286        PARAMSETDEF(state) { setState(arg1->getDouble()); return 0; }
     287        PARAMGETDEF(cstate) { arg1->setDouble(neuro->state); }
     288        PARAMSETDEF(cstate) { setCurrentState(arg1->getDouble()); return 0; }
     289        PARAMGETDEF(hold) { arg1->setInt((neuro->flags&(Neuro::HoldState)) ? 1 : 0); }
     290        PARAMSETDEF(hold) { neuro->flags = (neuro->flags&~Neuro::HoldState) | (arg1->getInt() ? Neuro::HoldState : 0); return 0; }
     291        PARAMGETDEF(channels) { arg1->setInt(getChannelCount()); }
     292        PARAMSETDEF(channels) { setChannelCount(arg1->getInt()); return 0; }
     293        PARAMPROCDEF(p_getstate) { arg2->setDouble(getState(arg1->getInt())); }
     294        PARAMPROCDEF(p_setstate) { setState(arg1[0].getDouble(), arg1[1].getInt()); }
     295        PARAMPROCDEF(p_setcstate) { setCurrentState(arg1[0].getDouble(), arg1[1].getInt()); }
     296        PARAMGETDEF(creature);
     297        PARAMGETDEF(part);
     298        PARAMGETDEF(joint);
     299        PARAMGETDEF(position_x);
     300        PARAMGETDEF(position_y);
     301        PARAMGETDEF(position_z);
     302        PARAMGETDEF(fields);
     303        PARAMGETDEF(neurodef);
     304        PARAMGETDEF(classObject);
    305305#undef STATRICKCLASS
    306306
    307   static Param& getStaticParam();
     307        static Param& getStaticParam();
    308308};
    309309
Note: See TracChangeset for help on using the changeset viewer.