Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

https://github.com/RaymondLab/Code
25 June 2024, 13:39:08 UTC
  • Code
  • Branches (12)
  • Releases (0)
  • Visits
    • Branches
    • Releases
    • HEAD
    • refs/heads/Calibration
    • refs/heads/Calibration2
    • refs/heads/Master
    • refs/heads/VerticalTracking
    • refs/heads/code_generalization
    • refs/heads/consolidation_project_241B
    • refs/heads/local_configuration_241B
    • refs/heads/revert-2-consolidation_project_241B
    • refs/heads/rig241b_driftfix_sign
    • refs/heads/smr_to_smrx
    • refs/heads/tracking_dev
    • refs/tags/v1.0.0
    No releases to show
  • 202e75e
  • /
  • Experiment Protocols
  • /
  • Parameters_Universal_Ella.s2s
Raw File Download
Take a new snapshot of a software origin

If the archived software origin currently browsed is not synchronized with its upstream version (for instance when new commits have been issued), you can explicitly request Software Heritage to take a new snapshot of it.

Use the form below to proceed. Once a request has been submitted and accepted, it will be processed as soon as possible. You can then check its processing state by visiting this dedicated page.
swh spinner

Processing "take a new snapshot" request ...

Permalinks

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
  • revision
  • snapshot
origin badgecontent badge Iframe embedding
swh:1:cnt:42b587bb05f6978a485bfe301e845f20c1dec56e
origin badgedirectory badge Iframe embedding
swh:1:dir:97cac15163343d339bd772db242996bd771de50f
origin badgerevision badge
swh:1:rev:9f44957f9f0ed658a3db815890042989af1f673d
origin badgesnapshot badge
swh:1:snp:5000b5dcf61aa2cac987bbe6af9204d011668dda
Citations

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • content
  • directory
  • revision
  • snapshot
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Tip revision: 9f44957f9f0ed658a3db815890042989af1f673d authored by GracelessGhost on 11 June 2020, 21:49:00 UTC
Add a line to the demo
Tip revision: 9f44957
Parameters_Universal_Ella.s2s
' UNIVERSAL PARAMETERS

'--------------------------------------------------------------------------------
' SINE PARAMETERS
'--------------------------------------------------------------------------------
var sinHzChair := 1;
var sinPhChair := -90;
var actualChairPh;
var sinHzDrum := 1;
var sinPhDrum := 90;
var actualDrumPh;
var sineOn% := 0;

'--------------------------------------------------------------------------------
' STEP PARAMETERS
'--------------------------------------------------------------------------------
var stepPeriod := 2000;
var stepLength := 500;
var stepStim := 0;
var stepAmpChair := 10;
var stepAmpDrum := 10;
var sRest2;
var sStart;
var sLength;
var sLength1;
var sRest1;
var sAmpChair;
var sAmpDrum;
var sAmpChairN;
var sAmpDrumN;
var stepLen1 := 0;
var stepLen2 := 0;
var stepLen3 := 0;
'For video alignment pulse - duration
var pulseDurationV := 33;
'For video alignment pulse - time between pulses
var pulseWaitV := 1000 - pulseDurationV - 5;
var pulsePeriod := 1000;
var checkConfig := 1;


'--------------------------------------------------------------------------------
' PULSE PARAMETERS
'--------------------------------------------------------------------------------
var pWait := 0;
var pNumber := 1;
var pDuration;
var pInterval;
var pStart;
var pulseDuration := 500;
var pulseInterval := 0;
var pWait2 := 0;
var pulsePhase := 0 ;
var stepLight := 0;
var lightDur := 500;
var lightStart := 0;
var everyNCycles := 1;


'--------------------------------------------------------------------------------
' EXPERIMENT PARAMETERS
'--------------------------------------------------------------------------------
var nBlocks% := 5;                 'Number of run-test blocks in exmpt
var nTestreps% := 0;               'Number of times to repeat 40 sec test
var runLength := 300;             'Seconds to run protocol in each block(300 for 5 min)
var testLength := 0;             'Seconds to test
var expmtLoc% := 1;
var prePostNum := 1;
var trainLoc% := 1;
var trainAmount := 0;
var expmtMode := 2;               'expmtMode: 0=off, 1=0x, 2=2x, 3=ipsi stim, 4=contra stim
var testString$;
var runExpmt% := 0;               ' Random note: % denotes integer types
var rep% := 0;                    'Rep (5min run, 40 sec test)
var test% := 1;                   'test: 0=run testLength, 1=test testLength, 2=init&wait 20 sec, 3=init&wait 10 sec,  4=init&wait runLength
var testrep% := 0;
var goalTime := 1000000000;    'maximum time the motor is allowed to run for
var flashon% := 1;
var waitLength := 300;
var prevTime := 0;
var startTracking% := 0;

'--------------------------------------------------------------------------------
' TRACKING PARAMETERS
'--------------------------------------------------------------------------------
var delta := .001; 'TEMPORARY VALUE'
var saccadeThreshold := 1; 'TEMPORARY VALUE'
var gain := 5;  'TEMPORARY VALUE'
var gainCeiling := 5; 'TEMPORARY VALUE'
var nullEyePos := 0;
var eyePos := 0;
var preTest% := 1; 'variable to check if test was run for first time to take baseline eye position'
var LeakInstabilityScale := -1; '-1 for leak, 1 for instability'
var leakOrInstability;
var incrementSize := .5;
var drumDriftFix% := 1;

'--------------------------------------------------------------------------------
' MISC PARAMETERS
'--------------------------------------------------------------------------------
var SampleWindow%;
var comment$;
var vidOn := 0;
var stepOn% := 0;
var fullPulse := 0;
'Voltage Range: check in Edit -> Edit Parameters
var MaxVoltage := 10;
var driftFix := 1;
var centerLineChair := 0;
var centerLineDrum := 0;
var testStim := 0;
var rotationVelocity := 0.02;
var radianConversion := 57.295779513; 'divide a value in degrees by this number to convert to radians - from Spike2 manual'
var measuredZeroChair := 0;
var measuredZeroDrum := 0;

'--------------------------------------------------------------------------------
' TOOLBAR PARAMETERS
'--------------------------------------------------------------------------------
const NewFilePos        := 2;
const InitPos           := NewFilePos+1;
const CommentPos        := InitPos+1;
const LightPos          := CommentPos+1;
const LaserPos          := LightPos+1;
const SinePos           := LaserPos+1;
const SineConfigPos     := SinePos+1;
const PulsePos          := SineConfigPos+1;
const PulseConfigPos    := PulsePos+1;
const VidPos            := PulseConfigPos+1;
const StepPos           := VidPos+1;
const StepConfigPos     := StepPos+1;
const TrackPos          := StepConfigPos+1;
const TrackConfigPos    := TrackPos+1;
const ExpmtPos          := TrackConfigPos+1;
const ExpmtConfigPos    := ExpmtPos+1;

const HTVELChCom% := 1;
const HHVELChCom% := 2;
const htposCh% := 3;
const hhposCh% := 4;
const heposCh1% := 5;
const heposCh2% := 6;
const hhvelCh% := 8;
const htvelCh% := 13;

'--------------------------------------------------------------------------------
' SINE FUNCTIONS
'--------------------------------------------------------------------------------
Func ToolbarSineStart%()
  prevTime := MaxTime();
  measuredZeroChair := ChanMeasure(hhposCh%, 2, prevTime-2, prevTime-.5);
  measuredZeroDrum := ChanMeasure(htposCh%, 2, prevTime-2, prevTime-.5);
  SampleKey( "S" );
  sineOn% := 1;
  Yield();
  ToolbarSet(SinePos, "Sine Off",ToolbarSineStop%);
  Return( 1 );
End

Func ToolbarSineStop%()
  SampleKey( "s" );
  sineOn% := 0;
  ToolbarSet(SinePos, "Sine On",ToolbarSineStart%);
  Return( 1 );
End

Func ToolbarSineConfig%()
  DlgCreate("Sine settings");  'Start new dialog
  DlgReal(1,"Chair Freq (Hz)",0,50);
  DlgReal(2,"Chair Peak Velocity (deg/sec)",0,100);    'set to 0 if not using Chair
  DlgReal(3,"Chair Phase (degree)",-180,180);
  DlgReal(4,"Drum Freq (Hz)",0,50);
  DlgReal(5,"Drum Peak Velocity (deg/sec)",0,100);   'set to 0 if not using Drum
  DlgReal(6,"Drum Phase (degree)",-180,180);
  DlgShow(sinHzChair,sinAmpChair, sinPhChair, sinHzDrum, sinAmpDrum,  sinPhDrum);

  SetPulseSettings%();

  SetSequencerValues();
  Return(1);
End

'--------------------------------------------------------------------------------
' LIGHT FUNCTIONS
'--------------------------------------------------------------------------------
Func ToolbarLightOn%()
  SampleKey( "L" );
  Toolbarset(LightPos,"Light Off", ToolbarLightOff%);
  Return( 1 );
End

Func ToolbarLightOff%()
  SampleKey( "l" );
  Toolbarset(LightPos,"Light On", ToolbarLightOn%);
  Return( 1 );
End

Proc runFlash()
  if flashon% = 1 then
      ToolbarLightOn%();
  endif;
  Yield(.2);
  ToolbarLightOff%();
End

'--------------------------------------------------------------------------------
'Turn both lasers on/off
'--------------------------------------------------------------------------------
Func ToolbarLasersOn%()
  SampleKey( "Z" );
  Toolbarset(LaserPos,"Lasers Off", ToolbarLasersOff%);
  Return( 1 );
End

Func ToolbarLasersOff%()
  SampleKey( "z" );
  Toolbarset(LaserPos,"Lasers On", ToolbarLasersOn%);
  Return( 1 );
End

'--------------------------------------------------------------------------------
'Start sine wave/pulses for video
'--------------------------------------------------------------------------------
Func ToolbarVidOn%()
  vidOn := 1;
  Yield();
  pulseDurationV := 33; 'For video alignment pulse
  pulseWaitV := 1000*1/sinHzChair - pulseDurationV - 5;    'For video alignment
  SetSequencerValues();
  SampleKey( "V" );
  Toolbarset(VidPos,"Video Off", ToolbarVidOff%);
  Return( 1 );
End

Func ToolbarVidOff%()
  vidOn := 0;
  Yield();
  SampleKey( "v" );
  Toolbarset(VidPos,"Video On", ToolbarVidOn%);
  Return( 1 );
End

'--------------------------------------------------------------------------------
' PULSE FUNCTIONS
'--------------------------------------------------------------------------------
Func ToolbarPulseConfig%()
  DlgCreate("Pulse settings");  'Start new dialog
  'DlgReal(1,"Period (ms)",0,300000);
  DlgReal(1,"Number of Pulses",0,1000);
  DlgReal(2,"Pulse duration (ms)",0,5000);
  DlgReal(3,"Interpulse interval (ms)",0,5000);
  DlgReal(4,"Pulse phase (deg)",0,360);
  DlgReal(5, "Pulses Occur Every X Cycles?", 1, 10000);
  DlgShow(pNumber, pulseDuration, pulseInterval,pulsePhase, everyNCycles);
  SetPulseSettings%();
  Return( 1 );
End

Func SetPulseSettings%()
  pulsePeriod := 1/sinHzChair * 1000;
  fullPulse := 0;
  pWait := (pulsePeriod/2) - 4 - (pNumber *(pulseDuration + pulseInterval+1));

  if pWait < 0 then
      pWait := 0 ;
      fullPulse := 1; 'Immediate switching between states
  endif;
  pDuration := pulseDuration -2;
  pWait2 := pWait-2;
  pInterval := pulseInterval;


  if pInterval > 1 then
      pInterval := pulseInterval -3;
  endif;


  SetSequencerValues();

  Return(1);
End

'--------------------------------------------------------------------------------
' STEP FUNCTIONS
'--------------------------------------------------------------------------------
Func ToolbarStepOn%()
  if (stepStim = 0) and (stepLight = 0) then
  	SampleKey ( "T" );
  	ToolbarSet(StepPos, "Step Stop", ToolbarStepOff%);
  else
      if stepLight = 1 and stepStim = 0 then
        stepOn% := 1;
        prevTime := MaxTime();
        measuredZeroChair := ChanMeasure(hhposCh%, 2, prevTime-2, prevTime);
        measuredZeroDrum := ChanMeasure(htposCh%, 2, prevTime-2, prevTime);
      docase
          case lightDur = stepLength and lightStart = 0 then
              SampleKey ("t");   ' Entire step

          case stepLen1 = 0 then
              ' Aligned to beginning of step
              SampleKey("b");

          case stepLen3 = 0 then
              'Aligned to end of step
              SampleKey("e");

          else
              ' Somewhere in the middle of step
              SampleKey ("d");   ' Delayed/partial

          endcase;
          ToolbarSet(StepPos, "Step Stop", ToolbarStepOff%);
      endif;
      if stepStim = 1 and stepLight = 1 then
          SampleKey ( "u");      '***Currently non functional 8/2/12?
          ToolbarSet(StepPos, "Step Stop", ToolbarStepOff%);
      endif;
  endif;
  Return (1);
End

Func ToolbarStepOff%()
  SampleKey( "I" );
  stepOn% := 0;
  ToolbarSet(StepPos, "Step Start", ToolbarStepOn%);
  Return( 1 );
End

Func ToolbarStepConfig%()
  ' User dialog
  StepConfigWindow();
  DlgShow(stepPeriod, stepLength, stepAmpChair, stepAmpDrum, stepStim, pulseDuration, pulseInterval, stepLight, lightDur, lightStart);

  ' Convert to exact numbers, accounting for software delays
  sRest1 := (stepPeriod  - stepLength - stepLength)/2 - 3;
  sLength := stepLength - 3;
  sRest2 := sRest1 - 1;

  ' Chair and drum velocity
  sAmpChair := ChairVel2Int32%( stepAmpChair );   ' Amp chair
  sAmpChairN := 0-sAmpChair;                      ' Amp chair (opposite direction)
  sAmpDrum := DrumVel2Int32%( stepAmpDrum );      ' Amp drum
  sAmpDrumN := 0-sAmpDrum;                        ' Amp drum (opposite direction)

  ' Light pulse
  if stepLight = 1 then

      ' If light pulse is not exactly the same as step pulse, break into 3 segments
      if lightDur <> stepLength or lightStart <> 0 then
          stepLen1 := max(lightStart - 3, 0);                         ' Chair alone
          stepLen2 := lightDur - 2;                                   ' Chair+light
          stepLen3 := max(stepLength - lightDur - max(lightStart,2) - 2,0);  ' Chair alone

          if stepLen3 = 0 then   'Small adjustment to account for delay if light aligned to end of step
              stepLen2 := stepLen2-1;
  endif;
      endif;

  endif;

  if stepStim = 1 then
  	pNumber := trunc((stepLength-4)/(pulseDuration + pulseInterval));
  	pDuration := pulseDuration -2;
  	pInterval := pulseInterval -3;
  	sLength1 := stepLength - ((pulseDuration + pulseInterval)*pNumber)-4;
  endif;

  'testing
  SetPulseSettings%();
  Yield();
  SetSequencerValues();
  Return (1);
End

Proc StepConfigWindow()
  DlgCreate("Step settings"); 'Start new dialog for entering step commands
  DlgReal(1,"Total Period (ms)", 0, 15000);
  DlgReal(2,"Step length (ms)", 0, 15000);
  DlgReal(3,"Chair Velocity (deg/sec)", -100, 100);
  DlgReal(4,"Drum Velocity (deg/sec)", -100, 100);
  DlgCheck(5,"Stimulate");
  DlgReal(6, "Pulse duration (ms)", 0, 5000);
  DlgReal(7, "Interpulse interval (ms)", 0, 5000);
  DlgCheck(8, "Light");
  DlgReal(9, "Light duration (ms)", 0, 5000);
  DlgReal(10, "Start time rel. step", 0, 5000);
End

'--------------------------------------------------------------------------------
' STIM/PULSE FUNCTIONS
'--------------------------------------------------------------------------------
Func ToolbarStimOn%()
  if fullPulse = 1 then
      SampleKey( "Q" );
  else
      SampleKey("P");
  endif;
  sineOn% := 0;
  Yield();
  Toolbarset(PulsePos,"Pulse Off", ToolbarStimOff%);
  Return( 1 );
End

Func ToolbarStimOff%()
  SampleKey( "p" );
  Yield();
  SampleKey( "I" );
  Yield();
  sineOn% := 0;

  Toolbarset(PulsePos,"Pulse On", ToolbarStimOn%);
  Return( 1 );
End

'--------------------------------------------------------------------------------
' TRACKING FUNCTIONS
'--------------------------------------------------------------------------------
'Constantly updates to track the eye movements of the mouse and adjust the drum to the same position'
'We don't want to move the chair at all, just the drum'
'Try to figure out how to change gain'
Func trackEye%()

  prevTime := MaxTime();
  ' var eye1Position := ChanValue(heposCh1%, prevTime);
  ' var prevEye1Position := ChanValue(heposCh1%, prevTime-delta);
  ' var eye2Position := ChanValue(heposCh2%, prevTime);
  ' var prevEye2Position := ChanValue(heposCh2%, prevTime-delta);
  '
  ' 'here do we want a slope (aka divide by delta) or just a difference?'
  ' 'currently averaging two eye channels, could try to do something to find the best eye channel'
  ' var eyePosChangeAvg := (eye1Position-prevEye1Position + eye2Position-prevEye2Position) / 2 / delta;
  '
  ' 'want to change this so that it uses the degree value and calculates the velocity change in response to that'
  '
  ' if eyePosChangeAvg > saccadeThreshold then 'need to find real value for threshold' 'OR MAYBE DON'T NEED THRESHOLD AT ALL AND JUST ALWAYS TRACK?
  '   var eyePosChangeScaled := eyePosChangeAvg * gain;
  '   DrumDegreesPerSecondOffset  :=  (DrumDegreesPerSecondOffsetDefault - eyePosChangeScaled) * DrumResetDirection * LeakInstabilityScale; 'this has to be changed to reflect the correct math for the eye tracking'
  ' else
  '   DrumDegreesPerSecondOffset := 0; 'is this how we say don't change position/stay constant??
  '   'Maybe:'
  '   'ToolbarInit%();
  ' endif
  ' SetSequencerValues();
  ' Return(1);

  'temporary - getting eye position by averaging both channels - eventually want to update to reflect best choice channel'
  var currEye1Pos := ChanValue(hhposCh%, prevTime);'ChanValue(heposCh1%, prevTime);
  var currEye2Pos := ChanValue(hhposCh%, prevTime);'ChanValue(heposCh2%, prevTime);
  var currEyePosAvg := (currEye1Pos + currEye2Pos) / 2;

  var degreeDiffScaled := (currEyePosAvg - nullEyePos) * gain; 'MAKE SURE THIS IS HOW WE GET THAT DEGREE VALUE'
  DrumDegreesPerSecondOffset := (degreeDiffScaled) * DrumResetDirection * LeakInstabilityScale;
  'make sure that the drum is going the right way'

  SetSequencerValues();
  Return(1);
End

Func ToolbarTrackConfig%() 'All of the values in here are guesses - may have to change how they're input, etc.
  'also need to figure out units for everything'
  DlgCreate("Eye Tracking settings");  'Start new dialog
  DlgReal(1,"Delta (s)",.000001,10);
  DlgReal(2,"Gain start value",.05, 10);
  DlgReal(3,"Gain end value",.05, 10);
  DlgReal(4,"Size of increments",.05, 1);
  DlgList(5, "Train for leak or instability", "Leak|Instability");
  DlgShow(delta, gain, gainCeiling, incrementSize, leakOrInstability);

  SetTrackingSettings%();

  Return(1);
End

'this will only need to be used if i can't just directly set everything from here/if calculations will need to be done
Func SetTrackingSettings%()
  'allows leak or instability to be chosen in menu, and scales velocities accordingly'
  docase
  case leakOrInstability = 0 then 'leaky'
    LeakInstabilityScale := -1;
  case leakOrInstability = 1 then 'unstable'
    LeakInstabilityScale := 1;
  endcase

  'set number of blocks to go through before incrementing
  'for this to really work the numbers have to be set such that everything ends up as a whole number'
  'instead change it so you give a min and a max and an increment size and it defines the number of blocks from that'
  if incrementSize = 0 or gainCeiling <= gain then
    nBlocks% := 1;
  else
    nBlocks% := (gainCeiling - gain + incrementSize) / incrementSize;
  endif;

  Return(1);
End

'finds the null eye position based on data from pre-training -- currently just averages means of both channels'
'possible improvement: find which one has less noise, use that channel to find null position'
Func findNullEyePos()
  prevTime := MaxTime();
  var chan1Mean := ChanMeasure(heposCh1%, 2, prevTime-testLength, prevTime);
  var chan2Mean := ChanMeasure(heposCh2%, 2, prevTime-testLength, prevTime);
  nullEyePos := (chan1Mean + chan2Mean) / 2;
End

Func ToolbarTrackEyeOn%()
  'SampleKey( "R" );
  Toolbarset(TrackPos,"Track Off", ToolbarTrackEyeOff%);
  startTracking% := 1;
  drumDriftFix% := 0;
  Return( 1 );
End

Func ToolbarTrackEyeOff%()
  'SampleKey( "r" );
  Toolbarset(TrackPos,"Track On", ToolbarTrackEyeOn%);
  startTracking% := 0;
  drumDriftFix% := 1;
  DrumDegreesPerSecondOffset := 0;
  Return( 1 );
End

'--------------------------------------------------------------------------------
' OTHER FUNCTIONS
'--------------------------------------------------------------------------------
Proc ToolbarConfig()
  ToolbarClear();     'Remove any old buttons

  ToolbarSet(0, "Idle",ToolbarIdle%);
  ToolbarSet(1, "Quit",  ToolbarQuit%);
  ToolbarSet(InitPos, "Init", ToolbarInit%);
  ToolbarSet(LightPos, "Light On", ToolbarLightOn%);
  ToolbarSet(LaserPos, "Lasers On", ToolbarLasersOn%);
  ToolbarSet(SinePos, "Sine On", ToolbarSineStart%);
  ToolbarSet(SineConfigPos, "Sine Config", ToolbarSineConfig%);
  ToolbarSet(PulseConfigPos, "Pulse Config", ToolbarPulseConfig%);
  ToolbarSet(PulsePos, "Pulse On", ToolbarStimOn%);
  ToolbarSet(VidPos, "Video On", ToolbarVidOn%);
  ToolbarSet(StepPos, "Step On", ToolbarStepOn%);
  ToolbarSet(StepConfigPos, "Step Config", ToolbarStepConfig%);
  ToolbarSet(ExpmtPos, "Run Expmt", ToolbarRunExpmt%);
  ToolbarSet(ExpmtConfigPos, "Expmt Config", ToolbarConfigExpmt%);
  ToolbarSet(CommentPos, "Comment", ToolbarComment%);
  ToolbarSet(NewFilePos, "New File", ToolbarNew%);
  ToolbarSet(TrackPos, "Track On", ToolbarTrackEyeOn%);
  ToolbarSet(TrackConfigPos, "Track Config", ToolbarTrackConfig%);
  Toolbar("", 231);
End

Proc WindowConfig()

  SampleClear(); 'Set the sampling configuration to a standard state

  'sequencer setup - returns zero if OK
  var err%; err% := SampleSequencer( SequencerFile$ );
  if err%<0 then
  	Message(Print$("I can't find your Sequencer File:%s",Error$(err%)));
  	halt
  endif

  'Channel 1
  SampleWaveform(HTVELChCom%,0,1000);  'Channel= 1, port= 0, ideal sampling rate= 1000 Hz
  SampleCalibrate(HTVELChCom%,"deg/s", DrumVoltage2Velocity, DrumVoltage2VelocityC);
  SampleTitle$(HTVELChCom%,"HTVEL");
  SampleComment$(HTVELChCom%, "Velocity Signal sent to drum");

  'Channel 2
  SampleWaveform(HHVELChCom%,1,1000);
  SampleCalibrate( HHVELChCom%, "deg/s", ChairVoltage2Velocity, ChairVoltage2VelocityC);
  SampleTitle$(HHVELChCom%,"HHVEL");
  SampleComment$(HHVELChCom%, "Velocity Signal sent to chair");

  'Channel 3
  SampleWaveform(htposCh%,2,1000);
  SampleCalibrate(htposCh%, "deg", DrumPosReadoutScale, DrumPosReadoutOffset);
  SampleTitle$(htposCh%,"htpos");
  SampleComment$(htposCh%, "Drum position");

  'Channel 4
  SampleWaveform(hhposCh%,3,1000);
  SampleCalibrate(hhposCh%,"deg", ChairPosReadoutScale, ChairPosReadoutOffset);
  SampleTitle$(hhposCh%,"hhpos");
  SampleComment$(hhposCh%, "Chair Position");

  'Channel 5
  SampleWaveform(heposCh1%,4,1000);
  SampleCalibrate(heposCh1%,"V",EyeVoltage2Position,EyeVoltage2PositionC);
  SampleTitle$(heposCh1%,"hepos1");
  SampleComment$(heposCh1%, "Eye Position 1");

  'Channel 6
  SampleWaveform(heposCh2%,5,1000);
  SampleCalibrate(heposCh2%,"V", EyeVoltage2Position,EyeVoltage2PositionC);
  SampleTitle$(heposCh2%,"hepos2");
  SampleComment$(heposCh2%, "Eye Position 2");

  'Channel 7 UCOMMENT THIS FOR EPHYS
  'SampleWaveform(7,6,1000);
  'SampleCalibrate(7,"V",1,0);
  'SampleTitle$(7,"phys");
  'SampleComment$(7, "phys");

  'Channel 8
  SampleWaveform(hhvelCh%,7,1000);
  SampleCalibrate(hhvelCh%,"deg/s",ChairVelReadoutScale,ChairVelReadoutOffset);
  SampleTitle$(hhvelCh%,"hhvel");
  SampleComment$(hhvelCh%, "Chair velocity");

  'Channel 9
  SampleEvent(9,0,2,1000);     'Func SampleEvent(chan%, port%, type%, rate);
  SampleTitle$(9,"TTL1");
  SampleComment$(9, "TTL1: Shutter");

  'Channel 10
  SampleEvent(10,1,2,1000);
  SampleTitle$(10,"TTL2");
  SampleComment$(10, "TTL2: IR LED");

  'Channel 11
  SampleEvent(11,2,2,1000);
  SampleTitle$(11,"TTL3");
  SampleComment$(11, "TTL3: L laser");

  'Channel 12
  SampleEvent(12,3,2,1000);
  SampleTitle$(12,"TTL4");
  SampleComment$(12, "TTL4: R laser");

  'Channel 13
  SampleWaveform(htvelCh%,8,1000);
  SampleCalibrate(htvelCh%,"deg/s",DrumVelReadoutScale,DrumVelReadoutOffset);
  SampleTitle$(htvelCh%,"htvel");
  SampleComment$(htvelCh%, "Drum Velocity");

  'Channel 30
  SampleTextMark(200);

  'Set optimise mode (do this last)
  SampleOptimise(1,1,0,2,50);

  'Continuous sampling
  SampleMode(1);

  'Create a spike2 data file and make the new window visible immediately
  SampleWindow% := FileNew(0,1);

  'Add smoothing to some channels
  'ChanProcessAdd(13, 1, 0.05);

  SetSequencerValues();

  'Hide all
  ChanHide(-1);

  'Show certain channels in a particular order
  ChanShow(1,2,3,4,5,6,7,8,9,10,11,12,13, 14,30,31);
  'ChanSelect(13,1);    'Select channel 13
  'ChanOrder(4,1,-3);   'Move selected channels
  '-----------------------------------------

  'Channel y-range (channel num, low, high)
  YRange( 1, -10, 10 );
  YRange( 2, -10, 10 );
  YRange( 3, -10, 10 );
  YRange( 4, -10, 10 );
  YRange( 5, -10, 10 );
  YRange( 6, -10, 10 );
  YRange( 7, -10, 10 );
  YRange( 8, -10, 10 );
  'YRange( htvelChan%, -10, 10 ); ' OPTIONAL D019 CHANNELS???
  'YRange( hhvelChan%, -10, 10 ); ' OPTIONAL D019 CHANNELS???

  ChanWeight(1,.5);           ' Make command channel smaller
  ChanWeight(2,.5);           ' Make command channel smaller

  XRange( 0, 20);      ' Set the default X axis time range

  ' Channel order
  ChanOrder(0, -1, "5, 4, 8, 13, 3, 2, 1, 12, 11, 10, 9, 30, 31");
  ' Background Colour'
  ViewColour(0,5);
  ' Font
  FontSet("Verdana", 8, 0);
  ' Chan colors
  chanColour(HTVELChCom%, 1, 28);
  chanColour(htposCh%, 1, 28);
  chanColour(htvelCh%, 1, 28);

  chanColour(HHVELChCom%, 1, 30);
  chanColour(hhposCh%, 1, 30);
  chanColour(hhvelCh%, 1, 30);

  chanColour(heposCh1%, 1, 1);
  chanColour(heposCh2%, 1, 1);


  ' Useful Zero line indicators
  HCursorNew(1);
  HCursor(1, 0, 1);

  HCursorNew(2);
  HCursor(2, 0, 2);

  HCursorNew(3);
  HCursor(3, 0, 3);

  HCursorNew(4);
  HCursor(4, 0, 4);

  HCursorNew(5);
  HCursor(5, 0, 8);

  HCursorNew(6);
  HCursor(6, 0, 12);
End

Func ToolbarNew%()
  WindowConfig();
  ' Make window full screen
  WindowVisible(3);
  Return (1);
End

Func ToolbarComment%()
  DlgCreate("Comment"); 'Start new dialog for entering comments
  DlgString(1,"Comment",200);
  DlgShow(comment$);
  SampleText(comment$);
  Return(1);
End

Func ToolbarRunExpmt%()
  runExpmt% := 1;
  rep% := 0;                   'Rep (5min run, 40 sec test)
  test% := 0;                  'test: 0=run testLength, 1=test testLength, 2=init&wait 20 sec, 3=init&wait 10 sec,  4=init&wait runLength
  testrep% := 0;                ' Changed from 0 to 1 5/2/14 so that VORD is only tested once at the beginning
  goalTime := MaxTime();

  ToolbarSet(ExpmtPos, "Quit Expmt",ToolbarQuitExpmt%);
  Return(1);
End

Func ToolbarQuitExpmt%()
  runExpmt% := 0;
  ToolbarInit%();
  ToolbarSet(ExpmtPos, "Run Expmt",ToolbarRunExpmt%);
  Return(1)
End

Func ToolbarInit%()
  ToolbarLightOff%(); Yield(.01);
  ToolbarSineStop%(); Yield(.01);
  prevTime := 0;  ' Reset prev time so sine offset code continues running in a new file

  SampleKey( "I" );

  Return( 1 );
End

Func ToolbarQuit%()
  SampleKey( "O" );
  Return( 0 );
End

' Send values to the sequencer
Proc SetSequencerValues()
  actualChairPh := ((sinPhChair + pulsePhase + 180) mod 360) - 180;
  actualDrumPh  := ((sinPhDrum  + pulsePhase + 180) mod 360) - 180;

  'Chair parameters
  SampleSeqVar( 23, ChairAmp2Int32%( ChairDegreesPerSecondOffset ) );
  SampleSeqVar( 27, ChairAmp2Int16%( sinAmpChair ) );
  SampleSeqVar( 28, Angle2Int32%( actualChairPh ) );
  SampleSeqVar( 29, Hz2Int32%( sinHzChair ) );
  SampleSeqVar( 55, ChairResetDirection); 'default chair direction
  'Drum parameters
  SampleSeqVar( 22, DrumAmp2Int32%( DrumDegreesPerSecondOffset ) );
  SampleSeqVar( 24, DrumAmp2Int16%( sinAmpDrum ) );
  SampleSeqVar( 25, Angle2Int32%( actualDrumPh ) );
  SampleSeqVar( 26, Hz2Int32%( sinHzDrum ) );
  SampleSeqVar( 65, DrumResetDirection); 'default drum direction

  'Pulse parameters
  SampleSeqVar( 33, pWait );
  SampleSeqVar( 34, pNumber );
  SampleSeqVar( 35, pDuration);
  SampleSeqVar( 36, pInterval);
  SampleSeqVar( 37, pStart);

  'Step parameters
  SampleSeqVar( 38, sRest2);
  SampleSeqVar( 39, sStart);
  SampleSeqVar( 40, sLength);
  SampleSeqVar( 41, sLength1);
  SampleSeqVar( 42, sRest1);
  SampleSeqVar( 43, sAmpChair);
  SampleSeqVar( 44, sAmpDrum);
  SampleSeqVar( 45, sAmpChairN);
  SampleSeqVar( 46, sAmpDrumN);
  SampleSeqVar( 47, stepLen1); ' For delayed light pulse with step
  SampleSeqVar( 48, stepLen2);
  SampleSeqVar( 49, stepLen3);
  SampleSeqVar( 50, pulseDurationV);
  SampleSeqVar( 51, pulseWaitV);
  SampleSeqVar( 52, pulsePeriod);
  SampleSeqVar( 54, everyNCycles);
  'Rotation Parameters
  SampleSeqVar( 66, rotationVelocity); 'This is a relative value
End

Func driftFix%()
  'drift back to 0 if sine wave isn't running
  docase
  case sineOn% = 1 or vidOn = 1 then
    var chairSign := 1; 'set default to 1 if phase = 0'
    var drumSign := 1;

    'figure out whether we want velocity to be positive or negative'
    if sinPhChair <> 0 then
      chairSign := sinPhChair / Abs(sinPhChair);
    endif
    if sinPhDrum <> 0 then
      drumSign := sinPhDrum / Abs(sinPhDrum);
    endif

    'convert from the sine amplitude signal to the actual position amplitude'
    var trueAmpChair := sinAmpChair / (2 * 3.14159 * sinHzChair);
    var trueAmpDrum := sinAmpDrum / (2 * 3.14159 * sinHzDrum);

    'calculates the center y value according to the phase given'
    var centerForPhaseChair := trueAmpChair * (1 - cos((-1 * sinPhChair)/radianConversion));
    var centerForPhaseDrum := trueAmpDrum * (1 - cos((-1 * sinPhDrum)/radianConversion));

    'takes into account that chair/drum may not start at 0'
    var theoreticalCenterChair := (centerForPhaseChair + measuredZeroChair) * chairSign;
    var theoreticalCenterDrum := (centerForPhaseDrum + measuredZeroDrum) * drumSign;

    'NOTE: there is something funky with the motors where there is an error that follows a sine wave from phase'
    'WE DON'T KNOW WHY, ONLY THAT IT HAPPENS'
    'the drift coefficients need to be calculated manually by testing the error for different phase offsets'
    var errorOffsetChair := ChairDriftFactor * sinAmpChair * sin(2 * sinPhChair / radianConversion);
    var errorOffsetDrum := DrumDriftFactor * sinAmpDrum * sin(2 * sinPhDrum / radianConversion);

    centerLineChair := (theoreticalCenterChair + errorOffsetChair) * ChairResetDirection;
    centerLineDrum := (theoreticalCenterDrum + errorOffsetDrum) * DrumResetDirection;

  else
    centerLineChair := 0;
    centerLineDrum := 0;
  endcase

  prevTime := MaxTime();
  ' Measure slope from last 1 cycle of chair/drum position feedback
  var hhposSlope := ChanValue(hhposCh%, prevTime) - ChanValue(hhposCh%, prevTime-(1/sinHzChair));
  var htposSlope := ChanValue(htposCh%, prevTime) - ChanValue(htposCh%, prevTime-(1/sinHzDrum));
  var hhposPos := ChanMeasure(hhposCh%, 2, prevTime-(1/sinHzChair), prevTime);
  var htposPos := ChanMeasure(htposCh%, 2, prevTime-(1/sinHzDrum), prevTime);

  ' Scales *1 for D253, *-1 for D019
  ChairDegreesPerSecondOffset :=  (ChairDegreesPerSecondOffsetDefault - hhposSlope/4 - hhposPos/4 - centerLineChair/4) * ChairResetDirection;
  if drumDriftFix% = 1 then
    DrumDegreesPerSecondOffset  :=  (DrumDegreesPerSecondOffsetDefault - htposSlope/4 - htposPos/4 - centerLineDrum/4) * DrumResetDirection;
  else
    if startTracking% = 1 then
      trackEye%();
    endif;
  endif;
  SetSequencerValues();
End
'--------------------------------------------------------------------------------
' CONVERSION FUNCTIONS
'--------------------------------------------------------------------------------

' Angles in the range [-180,180] should span [-2147483648.0,2147483647.0]
Func Angle2Int32%( angle )
  Return( angle * 2147483647.0 / 180 );
End

' Rates are calculated in degrees per sequencer step, with one degree being 11930465.
Func Hz2Int32%( hz )
 'This assumes a sequencer rate of 1 kHz.
  Return( hz * 11930465 * 360 / 1000 );
End

' Amplitudes must be converted such that [ 0, 32768 ] spans the positive range of the dac, e.g. [0, 5 ]
' We have to include the dac maximum and the degrees-per-second-to-voltage conversion factor. Does not include offset.
Func ChairAmp2Int16%( amp )
  Return( amp * ChairDegreesPerSecond2Voltage * 32768 / MaxVoltage  ) ;
End

Func DrumAmp2Int16%( amp )
  Return( amp * DrumDegreesPerSecond2Voltage * 32768 / MaxVoltage  )  ;
End

Func ChairAmp2Int32%( amp )
  Return( amp * ChairDegreesPerSecond2Voltage * 2147483647 / MaxVoltage  ) ;
End

Func DrumAmp2Int32%( amp )
  Return( amp * DrumDegreesPerSecond2Voltage * 2147483647 / MaxVoltage  )  ;
End

' steps
' Command velocities must be converted such that [ 0, 2147483647 ] spans the positive range of the dac, e.g. [0, 5 ]
' We have to include the dac maximum and the degrees-per-second-to-voltage conversion factor.
Func ChairVel2Int32%( amp )
  Return(  (amp + ChairDegreesPerSecondOffset) * ChairDegreesPerSecond2Voltage* 2147483647 / MaxVoltage  );
End

Func DrumVel2Int32%( amp )
  Return( (amp + DrumDegreesPerSecondOffset) * DrumDegreesPerSecond2Voltage * 2147483647 / MaxVoltage  );
End

back to top

Software Heritage — Copyright (C) 2015–2025, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Contact— JavaScript license information— Web API