-
Notifications
You must be signed in to change notification settings - Fork 0
/
Aplysia Feeding Kinetic Model.cpp
3595 lines (2912 loc) · 130 KB
/
Aplysia Feeding Kinetic Model.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Kinetic Slug Model.cpp : Defines the entry point for the console application.
// Rotation, translation, and everything!
// Simpler SlugModelRot getting rid of viscoelasticity and FV properties
// Simpler SlugModelNeuralInput putting neural recordings into the model
// doing scans for square waves across fitness, with fitness calculations for biting, swallow
// and rejection, without changing the biomechanics.
// XXII model with dynamic hinge.
#include <iostream>
#include <fstream>
using namespace std;
using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::string;
#include <cstdlib> // for exit function
FILE *izout;
FILE *valout;
FILE *neuralinputs;
FILE *animation;
FILE *rasterplot;
/* including some files of my own in the rebulid */
#include <string.h>
#include "math.h"
#include "stdio.h"
#include <vector>
#include <sstream>
#include <algorithm> // for std::replace
/* The constants */
#define eom 1 /*Equation of Motion, if this is one - using complex equation of motion (NEOM)
if this is two - using simple equation of motion (SEOM)
if this is three - using the new simple equation of motion (NSEOM)*/
#define inputcheck 1 /*if this equals 1 will let you input neuron values into printmodel (ignores GA)
if this does not equal one, code will run a GA */
#define protractfit -1 /*if this equals 1 fitcalc will give fitness for protraction
if this does not equal one, fitness will be given at retraction only*/
// #define debug /* to print debug info, uncomment this line or compile with "-D debug" */
#ifdef debug
#define debug_print(...) fprintf (stderr, __VA_ARGS__)
#else
#define debug_print(...) 0
#endif
const double RunDuration = 8.5; //seconds, length of time each individual is run
// TATE
double valueTBD;
const double pi = 3.14159265359;
const double StepSize = .000008; //.00001; size of the time step used to evaluate the Euler integrators in the model
const double timer = 0.01; //printmodel will print to the text file every "timer" seconds - keeps text file from being too big
const double izouttimer = 0.00005;
//Newton/Raphson constants
const double delta = 0.00001;
const double Error = 0.01;
//forces in mN, distances in meters, masses in grams
//odontophore mass and dimensions taken from hinge individual "Usurp"
const double Radius = .005; //radius of sphere odontophore in meters
const double r = 0.00125; //inner radius of the I1/I3 torus in m, remains constant in this model
const double Odonmass = 1.7; //mass of sphere in grams (labeled M in Guidebook)
const double I1I3mass = 1.3; //mass of torus in grams (labeled m in Guidebook)
// multi-ring I1/I3
const int N_RINGS = 5;
//Free parameters
const double LI2opt = 0.0225; //.0825; //optimal length of I2
const double LI1I3opt = 0.0417;//0.04; //optimal length of I1/I3
//activation parameters, from Yu et al 1999
const double tauact = 2.45; //sec
const double beta = 0.496;//0.703 <- reported in paper, this was with a tendon, the tendonless model is used in the code
const double Ao = 0.165;
const double g = 1; //different from Yu et al because of a typo in Yu et al.
const double uprimebound = -2.0; //uprime was bounded in the paper at 0, to fit the data better on deactivation this was changed
//Original was -0.3, seeing how this affects in vivo records.
//muscle parameters
const double FnotI2 = 240;//mN - maximum tension that I2 can produce, different from Yu to reproduce figure 2A
const double FnotI1I3 = 720; //mN - maximum tension that I1/I3 can produce
//visco-elastic hinge force parameters, from Sutton et al 2003 (hinge paper)
const double A1 = 0.617; //in mN/mm^2
const double A2 = 24.17; //in mN/mm
const double Xo = 13.27;
const double DX = 2.422;
const double B1 = -58.7; //in mN/mm^2
const double B2 = 12.6; //in mN/mm
const double B3 = -0.895; //in mN
const double B4 = 0.024;
const double C1 = 0.0997; //in mN/mm^2
const double C2 = 0.27;
const double C3 = -0.009;
const double D1 = -0.363;
const double D2 = 1.096;
const double E1 = 1.69;
const double E2 = -8.19;
const double E3 = 11.03;
const double AF1 = 0.288;
const double AF2 = 6.78;
const double viscdamp = 4.0; // simple model it was 4.0;
const double xp = 3.4; //mm, point in protraction when hinge force is first measured
const double xr = 6.9; //mm, point in retraction when hinge force is last measured
const double passiveoffset = 9.8; //shifts the hinge forces in order to get a biologically accurate rest position
const double lengthshift = 0.0; // 0.0; //-.0062; the shift on the hinge LT in order to get good active forces.
const double MAXSEAWEEDFORCE = 100; // the maximum force on the seaweed in mN.
const int seednum = 42;
const int inputrows = 740;
const int NeuronNum = 4; //number of neurons in the network
const double anglestiffness = .0001; //maximum additional rotation speed for odontophore in deg/second
//Tate: I2 variables
double lengthofI2 = 0;
double topphiangleofi2 = 0;
double bottomphiangleofi2 = 0;
//The furthest back point of the odontophore
double furthestbackxpoint = 0; //"backxpoint"
double furthestbackypoint = 0; //"backypoint"
//Where i2 and i1i3 are in contact (xvalue for top and bottom is constant at 0-r = -.00125)
double i1i3contacttopy = 0; //Ty1
double i1i3contactbottomy = 0; //By1
//Where i2 and the odontophore are first in contact
double ocontacttopx = 0; //Tx2
double ocontacttopy = 0; //Ty2
double ocontactbottomx = 0; //Bx2
double ocontactbottomy = 0; //By2
/* Variables used for opening input file*/
ifstream inputFile;
/*Arrays of stored values from input file*/
double positionarray[1000];
double radiusarray[1000];
double anglearray[1000];
double hingeFarray[1000];
double fitnessarray[1000];
double freqI1I3array[1000];
double freqN3array[1000];
double freqHingearray[1000];
double actI2array[1000];
double actI1I3array[1000];
double acthingearray[1000];
double seaweedforcearray[1000];
double freqI2array[1000];
double timearray[900000];
double i1i3poolarray[900000];
double i2poolarray[900000];
double i4poolarray[900000];
double hingepoolarray[900000];
int filerowcount = 0;
/* Value of columns in the input file*/
int numberColumns = 0;
/* Izhikevich Model Variables and Parameters*/
//Parameters -- currently set at compile time
const int NUMBEROFNEURONS = 11;
const double LAGTIME = .4;
// [0]- B31/32, [1] - B61/62, [2] - B8a, [3] - B3, [4] - B6, [5] - B9, [6] - B38, [7] - B10, [8] - B43, [9] - B7, [10] - B8b
const double ia[NUMBEROFNEURONS] = {.049,0.0207,.0338,.023,.0182,.0182,0.0165,0.0115,0.0557,0.0207,.0338}; //Parameters a-d
const double ib[NUMBEROFNEURONS] = {0.12,0.12,0.12,0.12,0.12,0.12,0.12,0.12,0.12,0.12,0.12};
const double ic[NUMBEROFNEURONS] = {-65,-65,-65,-65,-65,-65,-65,-65,-65,-65,-65};
const double id[NUMBEROFNEURONS] = {8,8,8,8,8,8,8,8,8,8,8};
double ii[NUMBEROFNEURONS] = {0,0,0,0,0,0,0,0,0,0,0}; // Applied current
//Variables
double membranePotential[NUMBEROFNEURONS];
double membraneRecovery[NUMBEROFNEURONS];
//Synapse Variables
const double Gsyn = .15;
const double Esyn = 40;
/* My function prototypes */
//calling the functions
double updateforces (double x, double ytop, double ybottom, double a, double ydot, double xdot, double oldx, double oldytop, double oldybottom, double olda,
double freqI2, double freqI1I3, double *aprimeI2, double *aprimeI1I3, double *force1, double *force2,
double *F1, double *HingeAct, double hingefrequency, double Oangle, double *hingeforce, double *externalforce);
//updateforces takes the current position of the odontophore and I1/I3 and the frequency of stimulation of the muscles
//and calculates the forces on the odontophore
double musclelengthI2 (double a, double x, double ytop, double ybottom, double Oangle);
//takes the position of the odontophore and calculates the length of the I2 muscle
double fixI2length (double);
//adjusts I2 length to give results that are consistent with the biology
double musclelengthI1I3 (double ytop, double ybottom);
//takes the position of I1/I3 and calculates the length of I1I3
double musclevelocityI2 (double oldx, double oldytop, double oldybottom, double olda, double x, double ytop, double ybottom, double a, double Oangle);
//takes the current and previous positions of the odontophore and I1/I3 and calculates the velocity of I2
double musclevelocityI1I3 (double ytop, double ybottom, double oldytop, double oldybottom);
//takes the change in position of I1/I3 and calculates the velocity of I1/I3
double activationI2 (double frequency, double *aprime);
//calculates the activation of I2 given the frequency of stimulation
double activationI1I3 (double frequency, double *aprime);
//calculates the activation of I1/I3 given the frequency of stimulation
double activationN3(double frequency, double *act, double time);
//calculates the activation of the shape change given the output frequency of N3
double secondactivationN3(double frequency, double *act, double time);
//calculates the activation of the shape change given the output frequency of N3
double passive (double);
//calculates the passive forces of a muscle given its normalized length
double lengthtens (double);
//calculates the length tension of a muscle given its normalized length
double forcevelocity (double);
//calculates the force velocity of a muscle given its velocity
double calchingeforce (double, double, double *);
//calculates the passive hinge force given the current position and velocity of the odontophore
double calchingeforce2 (double, double);
double updateposition (double *x, double *ytop, double *ybottom, double *a, double *xdot, double *ydot, double *adot, double f1, double f2, double actN3, double *Txc, double *Bxc, double *output, double *Oangle, double hingeforce);
//takes the forces on the odontophore and finds the new position of the odontophore and I1/I3
double calcphi (double x, double ytop, double ybottom, double a, double *Tphi, double *Bphi, double Oangle);
//calculates the angle of the straight piece of I2 with respect to the horizontal
//this is used in the calculation of I2's force
double contactslope (double *, double *, double *, double *, double *, double Oangle);
//calculates the slope of the tangent angle at the point of contact between the odontophore and
//I1/I3 and updates the point of contact (xc, yc)
void fitcalc (double x, double a, double oldx, double olda, double & fitness);
//updates an individual's fitness
double power(double, double);
//takes the first number and raises it to the second number's power (positive powers only)
double topEllipseSlope(double a, double xc, double rotation, double & yc);
double topEllipseSlope2(double a, double xc, double rotation, double & yc);
double bottomEllipseSlope(double a, double xc, double rotation, double & yc);
double topI1I3slope(double x, double xc);
/*slope of top I1I3 ring (bottom circle curve*/
double bottomI1I3slope(double x, double xc);
/*slope of bottom I1I3 ring (top circle curve*/
double OdonAngle(double x);
/*gives the odontophore's rotation given its position*/
double OdonAngle2(double x, double hingeforce, double radius, double oldodonangle);
/* This code rotates the odontophore as a function of hinge force and current radius */
void xcCalc(double a, double x, double rotation, double & Txc, double & Bxc, double & Tyc, double & Byc, double & topslope, double & bottomslope);
double activehingeforce (double activation, double velocity, double length);
void updateinputs(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2, double odontophorefreq, double i1i3freq, double hingefreq, double i2freq, string behaviorType, int count);
void updateinputsRejectionB(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2);
void updateinputsBite(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2);
void updateinputsSwallowB(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2);
void updateinputsSwallowA(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2);
void updateinputsRejectionA(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2);
void updateinputsSwallowPerturbed(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2);
bool openAndRead(string behaviorType);
int timeAdjuster(double timeArray[], double timeStamp, int count);
void updateDynamicInputs(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2, int count);
string returnFirstLine(string s);
int counter(string str);
int columnChecker();
double eulersMethod(double stepSize, double intialCondition, double intialFunctionValue);
double membranePotentialdt(double v, double u, int index);
double membraneRecoverydt(double v, double u, int index);
void izhikevichModel(double v, double u, int index);
double getMembranePotential(int index);
double evaluatefrequency(double time, double v, bool & firstSpike, bool & secondSpike, double & firstTime, double & secondTime, double & freq);
void saveFrequency(double time, double & odontophorefreq, double & i1i3freq , double & hingefreq, double & i2freq, int index, double & firstTime, double & secondTime, bool & firstSpike, bool & secondSpike, double & freq);
void motorPools(double freq[], double & odontophorefreq, double & i1i3freq , double & hingefreq, double & i2freq);
void updateinputsIzBite(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2, double odontophorefreq, double i1i3freq, double hingefreq, double i2freq);
void updateinputsIzSwallowPerturbed(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2, double odontophorefreq, double i1i3freq, double hingefreq, double i2freq);
void updateinputsIzSwallowA(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2, double odontophorefreq, double i1i3freq, double hingefreq, double i2freq);
void updateinputsIzSwallowB(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2, double odontophorefreq, double i1i3freq, double hingefreq, double i2freq);
void updateinputsIzRejectionB(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2, double odontophorefreq, double i1i3freq, double hingefreq, double i2freq);
void updateinputsIzRejectionA(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2, double odontophorefreq, double i1i3freq, double hingefreq, double i2freq);
void updateinputsIzExampleSwallow(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2, double odontophorefreq, double i1i3freq, double hingefreq, double i2freq);
void updateinputsIzSwallowBmoreaccurate(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2, double odontophorefreq, double i1i3freq, double hingefreq, double i2freq);
int rasterPlot(int index);
// [0]- B31/32, [1] - B61/62, [2] - B8a, [3] - B3, [4] - B6, [5] - B9, [6] - B38, [7] - B10, [8] - B43, [9] - B7, [10] - B8b
bool updateRasterPlot(int & b31, int & b61, int & b8a, int & b3, int & b6, int & b9, int & b38, int & b10, int & b43, int & b7, int & b8b);
void updateNeuromechanicalInputs(double time, double & freqI2, double & freqHinge, double & freqI1I3, double & freqN3, double & seaweedforce, double a, double frequencyiterationtime, double frequencyiterationtime2, double odontophorefreq, double i1i3freq, double hingefreq, double i2freq, int count);
double synapseModel(double s, double Vpost);
int main(int argc, char* argv[])
{
/* Taking an argument, parsing it to a string*/
std::string programName = argv[0];
std::string first_argument;
std::vector<std::string> all_args;
if (argc > 1) {
first_argument = argv[1];
all_args.assign(argv + 1, argv + argc);
}
/* Opening and reading a file*/
numberColumns = columnChecker();
if(openAndRead(first_argument) == true){
/* Absent minded code variable definitions */
const char* filename = "SlugOutput2.csv";
const char* filenamei = "Izhikevich.csv";
const char* filename2 = "NeuralInputs.txt";
const char* filenamea = "animationinfo.csv";
const char* filenamer = "rasterplotinfo.csv";
//variables used to calculate the muscle forces and odontophore position - explained when initialized
double x, y, xdot, ydot, adot, xacc;
double a, b;
double odontophoreangle;
double vol, force1, force2, time;
double oldx, oldy, olda, oldytop, oldybottom;
double aprimeI2, aprimeI1I3, aprimeN3, freqI2, freqI1I3, freqN3, actN3;
double F1; //visco-elastic hinge force, F1 from Sutton et al 2002
double hingeF = 0;
double xctop, xcbottom, yctop, ycbottom, ytop, ybottom, topslope, bottomslope, rotation;
// variables for multi-ring I1/I3
double aprimeI1I3_MULTIRING[N_RINGS];
double freqI1I3_MULTIRING[N_RINGS];
double xctop_MULTIRING[N_RINGS];
double xcbottom_MULTIRING[N_RINGS];
double yctop_MULTIRING[N_RINGS];
double ycbottom_MULTIRING[N_RINGS];
double ytop_MULTIRING[N_RINGS];
double ybottom_MULTIRING[N_RINGS];
double topslope_MULTIRING[N_RINGS];
double bottomslope_MULTIRING[N_RINGS];
//fitness calculation variables - explained when initialized
double fitness;
double SArea;
double fitcounter1, fitcounter2, fitcheck;
double fitpertime, oldfit, oldtime, totalfitness;
double oldxdot;
double aPrevious = 0;
double printtimer;
double eggtimer = 0;
double actI3 = 0;
double acthinge = 0;
int i = 1;
int I2inputcounter = 1;
int j = 1;
int k = 1;
int I1I3inputcounter1, I1I3inputcounter2, I1I3inputcounter3, RNinputcounter, Hingeinputcounter;
double printvar = 0;
double printvar2 = 0; // used in update position to ou tput the effective slope and phi
/* Absent minded code variable definitions */
int columncounter = 0;
int rowcounter = 0;
ifstream indata; //the input stream
float num; //variable for input value
float neuralvariables[12][inputrows];
double I1I3metafreq1 = 0;
double I1I3metafreq2 = 0;
double I1I3metafreq3 = 0;
double freqHinge = 0;
double startloop1 = 1;
double frequencyiterationtime = startloop1; //Code added to run loops of frequency code
double endfrequencytime = 1.1; //BLARF CHANGED TO ONLY CYCLE ONCE
double frequencystep = .1;
double frequencyiterationtime2 = 0;
double endfrequencytime2 = 0.1;
double frequencystep2 = .1; //BLARF CHANGED TO ONLY CYCLE ONCE
double checker = 1;
double period = 0;
double dummyvariable = 0; //just something to hand to functions for outputs that dont matter
double seaweedforce = 0; //This is added seaweed force on the odontophore
ifstream inFile;
valout = fopen(filename, "w");
if (!valout)
printf("Unable to open \"%s\" for writing!\n", filename);
izout = fopen(filenamei, "w");
if (!izout)
printf("Unable to open \"%s\" for writing!\n", filenamei);
animation = fopen(filenamea, "w");
if (!animation)
printf("Unable to open \"%s\" for writing!\n", filenamea);
rasterplot = fopen(filenamer, "w");
if (!rasterplot)
printf("Unable to open \"%s\" for writing!\n", filenamer);
//rasterplot information
// [0]- B31/32, [1] - B61/62, [2] - B8ab, [3] - B3, [4] - B6, [5] - B9, [6] - B38, [7] - B10, [8] - B43, [9] - B7, [10] - B8b
int peakB3132 = 0;
int peakB6162 = 0;
int peakB8a = 0;
int peakB8b = 0;
int peakB3 = 0 ;
int peakB6 = 0;
int peakB9 = 0;
int peakB38 = 0;
int peakB10 = 0;
int peakB43 = 0;
int peakB7 = 0;
bool peak = false;
//********INITIALIZING THE VARIABLES********
//variables for the physics - see geometry diagram in Valerie Snyder's notebook 4/24/02
//Guidebook pg. 1 diagram
a = Radius; //the major axis of the odontophore, the odontophore is intitialized as a sphere
b = (5.0*sqrt(5.0)/sqrt(a * 1000.0))/1000.0; //the minor axis of the odontophore, equation keeps the odontophore isovolumetric
x = -1 * a; //displacement of center of odontophore with respect to vertical line down the center of the I1/I3 torus
y = 0.00375; //major radius of I1/I3 ring
//r = sqrt(x*x + y*y) - Radius; //Pythagorean equality, r = thickness of I1/I3 torus (minor/cross-sectional radius)
vol = 2 * pi *r*r*y; //volume of the I1/I3 torus
xdot = 0; //velocity of odontophore
ydot = 0; //velocity of contraction/expansion of I1/I3 torus
adot = 0; //velocity of major axis of the odontophore
xacc = 0; //acceleration of the odontophore
//rotation = OdonAngle(x);
odontophoreangle = 90;
xctop = -0.0037;
xcbottom = -0.0037;
debug_print("=== INITIALIZATION ===\n");
xcCalc(a, -1*x, odontophoreangle, xctop, xcbottom, yctop, ycbottom, topslope, bottomslope);
ytop = yctop + sqrt(r*r - (-1*x - xctop)*(-1*x - xctop));
ybottom = ycbottom - sqrt(r*r - (-1*x - xcbottom)*(-1*x - xcbottom)); //initializing contact point
// initialize multi-ring I1/I3
for (i=0; i<N_RINGS; i++)
{
xctop_MULTIRING[i] = -0.0037;
xcbottom_MULTIRING[i] = -0.0037;
xcCalc(a, -1*x+(i*2*r), odontophoreangle, xctop_MULTIRING[i], xcbottom_MULTIRING[i], yctop_MULTIRING[i], ycbottom_MULTIRING[i], topslope_MULTIRING[i], bottomslope_MULTIRING[i]);
if (isnan(xctop_MULTIRING[i])) // ring not contacting odontophore
{
// These constants are where a ring will stay if it is not in
// contact with the odontophore. They were chosen somewhat
// arbitrarily: they are the positions of the original one-torus
// I1/I3 model (always in contact with the odontophore) when fully
// contracted at 20 Hz with simultaneous 20 Hz hinge stimulation.
ytop_MULTIRING[i] = 0.00341734;
ybottom_MULTIRING[i] = -0.00341734;
}
else // ring contacting odontophore
{
ytop_MULTIRING[i] = yctop_MULTIRING[i] + sqrt(r*r - power((-1*x+(i*2*r) - xctop_MULTIRING[i]),2));
ybottom_MULTIRING[i] = ycbottom_MULTIRING[i] - sqrt(r*r - power((-1*x+(i*2*r) - xcbottom_MULTIRING[i]),2)); //initializing contact point
}
}
force1 = 0.000; //horizontal force acting on odontophore
force2 = 0.000; //vertical force acting on the I1/I3 torus
//oldx, oldy, and oldr keep track of the previous position of the individual in order to calculate the velocity of I2 and adot
oldx = x;
oldy = y;
olda = a;
oldytop = ytop;
oldybottom = ybottom;
//Initialize arrays
for(int i = 0; i < NUMBEROFNEURONS; i++){
membranePotential[i] = -70;
membraneRecovery[i] = ib[i] * -70;
}
//activation variables, from Yu et al 1999
aprimeI2 = 0;
aprimeI1I3 = 0;
aprimeN3 = 0.01;
actN3 = 0;
//freqI2 and freqI1I3 are the frequency of stimulation of I2 and I1/I3 respectively
freqI2 = 0;
freqI1I3 = 0;
freqN3 = 0; //controls the length of the odontophore's major axis
//component of the visco-elastic hinge force, F1 from Sutton et al 2002
F1 = 0;
//fitness calculation variables
//fitness = 0.005 ; //0.1; //running total of the fitness an individual has earned
fitness = 0.0; //starting fitness at zero because we're not doing GA's right now.
SArea = 0; //amount of surface area exposed when the individual reaches peak protraction
fitcounter1 = 0; //counts consecutive negative velocities in order to determine when the protraction is finished
fitcounter2 = 0; //counts consecutive positive velocities in order to determine when retraction is finished
fitcheck = 0; //keeps track of whether the individual is currently protracting (1) or retracting (-1)
fitpertime = 0; //amount of fitness an individual recieves per second
oldfit = 0; //used to store the amount of fitness at the last peak protraction to calculate fitpertime
oldtime = 0; //used to store the time when the last peak protraction occurred to calculate fitpertime
totalfitness = 0; //fitness an individual would receive if the run were stopped (includes partial surface area or partial retraction)
time = 0; //keeps track of the amount of time the model has run so model will stop after the RunDuration is up
printtimer = 0;
double iztimer = 0;
I2inputcounter = 0;
I1I3inputcounter1 = 0;
I1I3inputcounter2 = 0;
I1I3inputcounter3 = 0;
RNinputcounter = 0;
Hingeinputcounter = 0;
//neuralinputs = fopen(filename2, "r"); //sets up the text file for reading the input.
//Print titles for SlugOutput2
fprintf(valout, "time,position,radius,angle,hingeF,fitness,freqI2,freqI1I3,freqN3,freqHinge,actI2,actI1I3,acthinge,fitness,seaweedforce\n");
//Titles for Izhikevich output
fprintf(izout, "time,MembranePotentialo,MembraneRecoveryo,ofreq,i1i3freq,hfreq,i2freq,current\n");
//Titles for animation info
fprintf(animation, "time,x,ytop,ybottom,");
for (int i = 0; i < N_RINGS; i++)
{
fprintf(animation, "ytop%d,ybottom%d,", i, i);
}
fprintf(animation, "a,odontophoreangle,xctop,xcbottom,lengthofI2,topphiangleofi2,bottomphiangleofi2,furthestbackxpoint,furthestbackypoint,i1i3contacttopy,i1i3contactbottomy,ocontacttopx,ocontacttopy,ocontactbottomx,ocontactbottomy,freqI2,freqI1I3,freqN3,freqHinge\n");
//Titles for rasterplot info
// [0]- B31/32, [1] - B61/62, [2] - B8a, [3] - B3, [4] - B6, [5] - B9, [6] - B38, [7] - B10, [8] - B43, [9] - B7, [10] - B8b
fprintf(rasterplot, "time,B31/32,B61/62,B8a,B3,B6,B9,B38,B10,B43,B7,B8b\n");
/* Reading the file for neural input */
i = 0;
j = 1;
/*while (j<inputrows)
{
printf("Scan3 %i \n", j);
i = j;
printf("Scan4 %i \n", j);
fscanf(neuralinputs, "%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f", &neuralvariables[1][i], &neuralvariables[2][i],&neuralvariables[3][i], &neuralvariables[4][i], &neuralvariables[5][i], &neuralvariables[6][i],&neuralvariables[7][i], &neuralvariables[8][i], &neuralvariables[9][i], &neuralvariables[10][i]);
printf("Scan %i \n", j);
j=j+1;
printf("Scan2 %i \n", j);
}*/
/*indata.open("NeuralInputs.txt"); // opens the file
if(!indata)
{ // file couldn't be opened
cerr << "Error Spam: file could not be opened" << endl;
exit(1);
}
else
{
cout << "Found It!" << endl;
} */
/* BLARF COMMENT REMOVING READING INPUT
// Reading the data into the model
indata >> num;
while ( !indata.eof() )
{
// keep reading until end-of-file
if (rowcounter > 11)
{
rowcounter = 0;
columncounter++;
}
neuralvariables[rowcounter][columncounter] = num;
//cout << "The next number is " << neuralvariables[rowcounter][columncounter] << endl;
rowcounter = rowcounter +1;
//cout << columncounter << endl;
//cout << rowcounter << endl;
indata >> num; // sets EOF flag if no value found
}
indata.close();
cout << "End-of-file reached.." << endl;
BLARF COMMENT REMOVING READING INPUT END */
//********ENDING INITIALIZATION********
/* Running the model here */
/*printf("%f\t%f \n", neuralvariables[1][I2inputcounter], neuralvariables[2][I2inputcounter]);
printf("%f\t%f \n", neuralvariables[1][1], neuralvariables[2][1]);
printf("%f\t%f \n", neuralvariables[1][3], neuralvariables[2][3]);*/
/* WHILE LOOP REMOVED while(frequencyiterationtime2 < endfrequencytime2) //a second loop to scan two dimensions
{
while(frequencyiterationtime < endfrequencytime) //loop added to do cyclic frequency checks
{ */
//redo of initialization for the run
//variables for the physics - see geometry diagram in Valerie Snyder's notebook 4/24/02
//Guidebook pg. 1 diagram
a = Radius; //the major axis of the odontophore, the odontophore is intitialized as a sphere
b = (5.0*sqrt(5.0)/sqrt(a * 1000.0))/1000.0; //the minor axis of the odontophore, equation keeps the odontophore isovolumetric
x = -1 * a; //displacement of center of odontophore with respect to vertical line down the center of the I1/I3 torus
y = 0.00375; //major radius of I1/I3 ring
//r = sqrt(x*x + y*y) - Radius; //Pythagorean equality, r = thickness of I1/I3 torus (minor/cross-sectional radius)
vol = 2 * pi *r*r*y; //volume of the I1/I3 torus
xdot = 0; //velocity of odontophore
ydot = 0; //velocity of contraction/expansion of I1/I3 torus
adot = 0; //velocity of major axis of the odontophore
xacc = 0; //acceleration of the odontophore
rotation = OdonAngle(x);
xctop = -0.0037;
xcbottom = -0.0037;
xcCalc(a, -1*x, rotation, xctop, xcbottom, yctop, ycbottom, topslope, bottomslope);
ytop = yctop + sqrt(r*r - (-1*x - xctop)*(-1*x - xctop));
ybottom = ycbottom - sqrt(r*r - (-1*x - xcbottom)*(-1*x - xcbottom)); //initializing contact point
force1 = 0.000; //horizontal force acting on odontophore
force2 = 0.000; //vertical force acting on the I1/I3 torus
//oldx, oldy, and oldr keep track of the previous position of the individual in order to calculate the velocity of I2 and adot
oldx = x;
oldy = y;
olda = a;
oldytop = ytop;
oldybottom = ybottom;
//activation variables, from Yu et al 1999
aprimeI2 = 0;
aprimeI1I3 = 0;
aprimeN3 = 0.01;
actN3 = 0;
//freqI2 and freqI1I3 are the frequency of stimulation of I2 and I1/I3 respectively
freqI2 = 0;
freqI1I3 = 0;
freqN3 = 0; //controls the length of the odontophore's major axis
freqHinge = 0;
//initialize freq for iz //TATE becareful not to mix up with freqi1i3 etc
double i1i3freq = 0;
double odontophorefreq = 0;
double hingefreq = 0;
double i2freq = 0;
//Averaging firing rates variables
double firstTime[NUMBEROFNEURONS];
double secondTime[NUMBEROFNEURONS];
bool firstSpike[NUMBEROFNEURONS];
bool secondSpike[NUMBEROFNEURONS];
double freq[NUMBEROFNEURONS];
for(int i = 0; i < NUMBEROFNEURONS; i++){
firstSpike[i] = false;
secondSpike[i] = false;
firstTime[i] = 0;
secondTime[i] = 0;
freq[i] = 0;
}
//component of the visco-elastic hinge force, F1 from Sutton et al 2002
F1 = 0;
//fitness calculation variables, making really low for bites!
fitness = 0.0; //running total of the fitness an individual has earned, tube manipulation
//fitness = x; //fitness for the maximum protraction trials of biting.
time = 0;
debug_print("\n=== ENTERING MAIN LOOP ===\n");
debug_print("Dreaming the impossible dream \n");
while(time < RunDuration) //runs the individual until time is greater than RunDuration
{
if (isnan(x))
{
printf("ABORTING: x is nan @ time = %f !\n", time);
exit(1);
}
if (isnan(y))
{
printf("ABORTING: y is nan @ time = %f !\n", time);
exit(1);
}
//NeuronOutput is from 0 to 1, multip ly be 20 to get freq from 0 to 20
freqI2 = 0;//circ.NeuronOutput(1) * 20;
freqI1I3 = 0;//circ.NeuronOutput(2) * 20;
freqN3 = 0;//circ.NeuronOutput(3) * 20;
I1I3metafreq1 = 0;
I1I3metafreq2 = 0;
I1I3metafreq3 = 0;
freqHinge = 0;
//Update Neural variables and seaweed force based on the current time
updateinputs(time, freqI2, freqHinge, freqI1I3, freqN3, seaweedforce, a, frequencyiterationtime, frequencyiterationtime2, odontophorefreq, i1i3freq, hingefreq, i2freq, first_argument, filerowcount);
for(int i = 0; i < NUMBEROFNEURONS; i++){
saveFrequency(time, odontophorefreq, i1i3freq , hingefreq, i2freq, i, firstTime[i], secondTime[i], firstSpike[i], secondSpike[i],freq[i]);
}
motorPools(freq, odontophorefreq, i1i3freq , hingefreq, i2freq);
//BLARF looking at first protraction first
//freqI1I3 = 0;
//freqN3 = 0;
//freqN3 = 15;
eggtimer += StepSize;
//actN3 = activationN3(freqN3, &aprimeN3, time);
actN3 = secondactivationN3(freqN3, &aprimeN3, time);
oldxdot = xdot; //for use in hinge fix
//take frequencies and determine the forces
//printvar2 = updateforces (x, ytop, ybottom, a, ydot, xdot, oldx, oldytop, oldybottom, olda, freqI2, freqI1I3, &aprimeI2, &aprimeI1I3, &force1, &force2, &F1, &acthinge, freqHinge);
printvar = force1;
//take frequencies and determine the forces
printvar = updateforces (x, ytop, ybottom, a, ydot, xdot, oldx, oldytop, oldybottom, olda, freqI2, freqI1I3, &aprimeI2, &aprimeI1I3, &force1, &force2, &F1, &acthinge, freqHinge, odontophoreangle, &hingeF, &seaweedforce);
//oldx, oldy, and olda are set equal to x, y, and a respectively before x, y, and a are updated to the new position
oldx = x;
oldy = y;
olda = a;
oldytop = ytop;
oldybottom = ybottom;
//take forces and the frequency of N3 and determine odontophore position
updateposition(&x, &ytop, &ybottom, &a, &xdot, &ydot, &adot, force1, force2, actN3, &xctop, &xcbottom, &dummyvariable, &odontophoreangle, hingeF);
//resetting the visco-elastic force to zero to prevent accumulation of visco-elastic forces over large amounts of time
//from overwelming the elastic hinge force
peak = updateRasterPlot(peakB3132, peakB6162, peakB8a, peakB3, peakB6, peakB9, peakB38, peakB10, peakB43, peakB7, peakB8b);
if ((xdot/oldxdot) < 0)
{
F1 = 0;
}
if(iztimer > izouttimer){
//Izhikevich Model Output
fprintf(izout, "%f,%f,%f,%f,%f,%f,%f,%f\n", time, membranePotential[3], membraneRecovery[3], odontophorefreq, i1i3freq, hingefreq, i2freq, ii[3]);
iztimer = 0.0;
}
if(peak){
fprintf(rasterplot, "%f,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", time, peakB3132, peakB6162, peakB8a, peakB3, peakB6, peakB9, peakB38, peakB10, peakB43, peakB7, peakB8b);
}
peak = false;
//Izhikevich Model Update -- seconds
for(int i = 0; i < NUMBEROFNEURONS; i++){
izhikevichModel(membranePotential[i], membraneRecovery[i], i);
}
eggtimer += StepSize;
time += StepSize; //time advances one time step, run will stop when time becomes larger than the RunDuration
printtimer += StepSize;
iztimer += StepSize;
if (printtimer > timer) //function will only print every printtimer seconds - keeps file from being too big
{
//print statement
//fprintf(valout, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,\n",time, x, freqI2, freqI1I3, freqN3, actN3, a, fitness, aprimeI2 - Ao, aprimeI1I3 - Ao, LI2opt*musclelengthI2 (a, x, y));
//fprintf(valout, "%f,%f,%f,%f,%f,\n",x, printvar2, printvar, passive(printvar), passive(printvar)*2*pi*FnotI2);
//fprintf(valout, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n", x, a, OdonAngle(x), lengthtens(printvar), printvar2, force1 - calchingeforce(x, xdot, &F1), calchingeforce(x,xdot,&F1), lengthtens(musclelengthI1I3(ytop,ybottom)), printvar, force2 * printvar);
//fprintf(valout, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,\n", time, x, ybottom, ytop, a, freqI2, freqI1I3, I1I3metafreq1, I1I3metafreq2, I1I3metafreq3, freqN3, freqHinge, -calchingeforce2(x, xdot), -activehingeforce(acthinge, xdot, x), printvar2, dummyvariable, printvar, acthinge, aprimeI1I3, aprimeI2, OdonAngle(x), fitness);
//This is the Fprint for the simulations in the example PDF's I sent Hillel.
fprintf(valout, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n", time, x, a, odontophoreangle, hingeF, fitness, freqI2, freqI1I3, freqN3, freqHinge, aprimeI2, aprimeI1I3, acthinge, fitness, seaweedforce);
fprintf(animation, "%f,%f,%f,%f,", time, x, ytop, ybottom);
for (int i = 0; i < N_RINGS; i++)
{
fprintf(animation, "%f,%f,", ytop_MULTIRING[i], ybottom_MULTIRING[i]);
}
fprintf(animation, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n", a, odontophoreangle, xctop, xcbottom, lengthofI2, topphiangleofi2, bottomphiangleofi2,furthestbackxpoint,furthestbackypoint,i1i3contacttopy,i1i3contactbottomy,ocontacttopx,ocontacttopy,ocontactbottomx,ocontactbottomy,freqI2, freqI1I3, freqN3, freqHinge);
//Izhikevich Model Output
//fprintf(izout , "%f,%f,%f\n", time, membranePotential, membraneRecovery);
//resets printtimer
printtimer = 0.0;
}
if (time > 0) //fitness function ignores the initial jiggle into the equilibrium position
// because of the delay in the activation function, no muscle moves before time = 0.4
{
//updates the fitness / surface area / fitcheck
fitcalc(x, a, oldx, olda, fitness); //commenting out the old fitness
//for odontophore protraction magnitude
/*if (x > fitness)
{
fitness = x;
} */
//fitcalcbite(x,a,oldx, olda, fitness);
}
}
debug_print("\n=== EXITING MAIN LOOP ===\n");
debug_print("that's another simulation completed at %f\t%f\n", frequencyiterationtime, frequencyiterationtime2);
/* While loop Removal
fprintf(valout, "%f,%f,%f\n", frequencyiterationtime, frequencyiterationtime2, fitness);
printf("that's another simulation completed at %f\t%f\n", frequencyiterationtime, frequencyiterationtime2);
frequencyiterationtime = frequencyiterationtime + frequencystep;
}
frequencyiterationtime = startloop1;
frequencyiterationtime2 = frequencyiterationtime2 + frequencystep2;
} While loop Removal end */
}
else{
cout << "\nERROR: Unreadable File... Too Many or Too Few Columns in File (" << numberColumns << ")... \nKINETIC MODEL INPUT: \n If you want to use an input file to the Kinetic model, include a comma delimited text file with 6 columns \n Alternatively, you can rename a previous SlugOutput2.csv file as SlugInput2.csv (should have 15 columns), and run that as input. \nNEUROMECHANICAL MODEL INPUT: \n If you want to use an input file to the Neuromechanical model, include a comma delimited text file with 5 columns \n \n \n";
}
}
/* The absent minded code that just runs after everything else works */
/* Putting in my function definitions */
double updateforces (double x, double ytop, double ybottom, double a, double ydot, double xdot, double oldx, double oldytop, double oldybottom, double olda,
double freqI2, double freqI1I3, double *aprimeI2, double *aprimeI1I3, double *force1, double *force2,
double *F1, double *HingeAct, double hingefrequency, double Oangle, double *hinge, double *externalforce)
/*updateforces takes the new and old position of the odontophore (x, oldx), the new and old radius of the I1/I3 torus
(y, oldy), the new and old major axes (a, olda), the velocity of the odontophore (xdot) velocity of the radius of the torus
(ydot), and the frequency of muscle stimulation for I2 and I1/I3 (freqI2, freqI1I3). The function uses these to calculate
the new horizontal force on the odontophore (f1 in the model, force1 in function) and the new vertical force on the I1/I3
torus (f2 in the model, force2 in the function). The function first calculates the lengths of I2 and I1/I3 using
musclelengthI2 and musclelengthI1I3. I2's length is renormalized using the function fixI2length. The velocities of the
muscles are then calculated using the musclevelocity functions. From the frequencies of stimulation of the muscles, the
activation of I2 and I1/I3 (actI2, actI1I3) are calculated. The passive force of each muscle is calculated by giving the
muscle's length to the function passive and then multiplying the result by the maximum force of the muscle (FnotI2 or FnotI1I3).
Using a Hill analysis the muscle tension = Fnot * act * FV * LT. This equation is used in the function with the passive
tension added. Because the muscle tension is along the muscle in direction, some geometry needed to be done in order to
determine the total horizontal force and total vertical force that was acting on the odontophore and I1/I3 torus. In order
to perform this calculation, the angle of the straight piece of I2 (phi) had to first be calculated. These derivations were
done on 5/14/02 in Val's first notebook. They are also in the Guidebook pg. 12-13. The visco-elastic hinge force was
calculated using the function calchingeforce. Since the hinge force was characterized from the horizontal direction it could
be added directly to the horizontal force acting on the odontophore.*/
{
double lengthI2, lengthI1I3, velocityI2, velocityI1I3, actI2, actI1I3, tensionI2, tensionI1I3;
double passiveI2, passiveI1I3;
double acthinge;
//double legx, legy, hyp; BLARF
//double Tphi, Bphi, A, B; BLARF
//double vertI2force, horI2force; BLARF
double Tphi, Bphi;
double effectivePhi;
//calculate the muscle lengths, are normalized
lengthI2 = musclelengthI2(a, x, ytop, ybottom, Oangle); //this will update phi
lengthI2 = fixI2length (lengthI2); //rescaling of I2 length to stay on lengthtension curve
lengthI1I3 = musclelengthI1I3 (ytop, ybottom);
// cancelling output for now *output = lengthI2;
//calculating muscle velocities, are normalized
velocityI2 = musclevelocityI2 (oldx, oldytop, oldybottom, olda, x, ytop, ybottom, a, Oangle);
velocityI1I3 = musclevelocityI1I3 (ytop, ybottom, oldytop, oldybottom);
//calculating activations
actI2 = activationI2 (freqI2, aprimeI2);
actI1I3 = activationI1I3 (freqI1I3, aprimeI1I3);
acthinge = activationI2 (hingefrequency, HingeAct);
//calculating the passive muscle forces
passiveI2 = FnotI2 * passive(lengthI2);
passiveI1I3 = 0.0; //taking out passive I1I3 forces FnotI1I3 * passive(lengthI1I3);
//calculating the muscle tensions
tensionI2 = FnotI2 * lengthtens (lengthI2) * forcevelocity (velocityI2) * actI2 + 1.0*passiveI2; //BLARF 1.8 for stable bites
tensionI1I3 = FnotI1I3 * lengthtens (lengthI1I3) * forcevelocity (velocityI1I3) * actI1I3 + passiveI1I3/2;
//update phi
calcphi (x, ytop, ybottom, a, &Tphi, &Bphi, Oangle);
effectivePhi = (Tphi - Bphi)/2;
//if(cos(effectivePhi) < 0)
//effectivePhi = pi/2;
//based on tensions, calculating force one and force two
//geometry done 5/14/02 -- pg 11 and 12 in Val's first lab notebook
//pg. 12-13 in Guidebook
//only including the elastic component visco = calchingeforce (x, xdot, F1);
*hinge = calchingeforce2(x,xdot) + activehingeforce(acthinge, xdot, x);
//ActiveHingeForce Here
//Putting in an active hinge with a basic Zajac McLT curve
*force1 = 2 * pi * tensionI2 * cos(effectivePhi) + *hinge + *externalforce; ///JEFF THIS IS WHERE THE EXTERNAL FORCE GOES!!!!
*force2 = 2 * tensionI1I3 * pi; //+ 2*pi*tensionI2*sin(effectivePhi) taking out I2component on I3 simplemodel;
//valueTBD = aprimeI2; //TATE
//Tate- save the values of I2 for animation
lengthofI2 = lengthI2;
topphiangleofi2 = Tphi;
bottomphiangleofi2 = Bphi;
return (lengthI2);
}
double calcphi (double x, double ytop, double ybottom, double a, double *Tphi, double *Bphi, double Oangle)
/*The function calcphi takes the position and shape of the odontophore (x, y, a) and calculates the angle of the straight
section of I2 with respect to the horizontal. The output is in the form of the length of the legs of the right triangle that
contains phi. The function updateforces can then used these lengths to convert muscle tension to muscle force in the desired