Putting robotics at your service™

Free shipping on orders over $200

FreeBasic SSC-32 Interpreter

Print view Share :
Previous topicNext topic

Page 1 of 2 [ 19 posts ]

1, 2
User avatar
Expert ( offline )
Posts: 293
Posted: 2010-09-10 20:03 
This program was developed to operate Peter Penguin, an animatronic that I am building, through a Lynxmotion SSC-32 Servo controller. The objective was to allow me to write ‘scripts' in a naturally descriptive manner. For example:

1. Move eyes left
2. Squint
3. Turn head right
4. Move eyes right slowly
5. Open eyes
6. Face forward

In the end, the project became a mini-programming like language, with directives such as Define Moves (creating a lookup table between the English description and the corresponding controller commands), Play Move, Start Script (to allow parallel execution of moves), Jump To {label}, Synchronize between scripts, Pause, etc…
The code is organized into three major sections:

1. Define Moves
2. Pre-Process all ‘scripts' for a ‘show'
3. Execute the scripts;

‘Define Moves' reads the lookup table from a file (the ‘show' data) and loads the description/controller commands into an array.

‘Pre-Process' the scripts converts the natural language descriptions and moves, into integer codes and array indices to either the controller command or to another location within the script. Each line in a script consists of three values, some of which are optional depending on the action. Action is what the line does, for example “PlayMove” sends a command to the SSC-32. Description is a user-friendly name for the action or move, such as “Move Eyes Right Slowly”. The third value is a numeric value and in most cases represents time in ms, often to specify a delay after sending a command to the SSC-32. During this delay, the software can continue to process other actions.

‘Execute' the scripts performs the actions defined in the show file, moving the penguin according to the defined script(s). The feature of being able to define multiple scripts is similar to having two GP players available on the SSC-32, only you can define more than two series of commands to execute in parallel (well, kinda in parallel… More like alternating commands from different scripts and using the delay time in the moves to execute other moves - timesharing). On my penguin, I can have one script moving the head, a second script moving the arms and a third script controlling the torso. The multi-tasking is done via software in this portion of the code. If you look at the source code attached, you also may note that moving the mouth – speaking – will be done in parallel with other moves; I will start an external process to play a .wav file and while it is running, the code will be performing A/D input from the circuit I developed (See my post viewtopic.php?f=2&t=6113) and moving the penguin mouth in synch.

Here is an example of the data file/script:
Code:
Begin,Moves
Look ahead,#0P1500 #1P1500
Look right,#0P1100 #1P1100
Look left,#0P2000 #1P2000
Cross-eyed,#0P2000 #1P1100
Look right slowly,#0P1100 #1P1100 T1500
Look ahead slowly,#0P1500 #1P1500 T1500
Look left slowly,#0P2000 #1P2000 T1500
Open eyes,#2P750
Close eyes,#2P2000
Blink eyes,#2P1200
Squint eyes,#2P1000
Squint eyes slowly,#2P1000 T2000
Open eyes slowly,#2P750 T3000
Close eyes slowly,#2P2000 T3000
Close Mouth,#3P570
Open Mouth 1,#3P600
Open Mouth 2,#3P680
Open Mouth 3,#3P790
Open Mouth Wide,#3P1005
End,Moves

StartScript,Main,0
Label, Repeat moves,
PlayMove,Look right,20
PlayMove,Look ahead,100
PlayMove,Look right slowly,20
ScriptPause,-,2000
PlayMove,Look ahead,20
ScriptPause,-,2000
PlayMove,Blink eyes,10
PlayMove,Open eyes,200
PlayMove,Blink eyes,10
PlayMove,Open eyes,200
PlayMove,Blink eyes,10
PlayMove,Open eyes,200
PlayMove,Squint eyes slowly,2000
PlayMove,Look right slowly,2000
PlayMove,Look left slowly,2000
PlayMove,Look ahead,1000
PlayMove,Open eyes,30
JumpTo,Repeat Moves.
EndScript,Main,0
End,Scripts


Eventually, I want to add additional sensors and conditional logic to the program, so that when alone or no one is near, the penguin will shift, flap his wings, blink and perform various bored movements seemingly at random. Then, when someone approaches, he will turn to look at them and react somehow… sometimes shyly… sometimes with a greeting… sometimes with a song!


Attachment:
Animatron.bas [6.85 KiB]
Downloaded 152 times

_________________
Heard in the workshop: PEBRAC...
User avatar
Guru ( offline )
Posts: 9258
Posted: 2010-09-13 10:01 
This is a perfect example of how easy it is to make an animatronic show from simple off the shelf components and simple programming. Excellent work! 8)

_________________
Jim Frye, the Robot Guy
http://www.lynxmotion.com
I've always tried to do my best...


User avatar
Expert ( offline )
Posts: 293
Posted: 2010-12-14 13:34 
Some additional details. I have been adding functionality to the program and debugged it once I had Peter assembled. For those of you who read code, the current version is attached. On request, I will supply sample data files...

"Animatron" has the following command set:

    PlayMove = send commands to SSC-32
    Say = play external sound file; will cause a servo (e.g. mouth servo) to synchronize to sound
    PlayScript = execute multiple scripts in parallel; script must be defined in same file
    ScriptPause = "Pause" or "Delay" command; pauses execution for n milliseconds
    StartScript = define new script; main script MUST be last in file
    EndScript = end of script routine definition
    JumpTo = "goto" command; label MUST exist (is not checked for)
    Label = definition of label used in "JumpTo" command
    SyncPoint = definition of scripts which will synchronize with other script(s)
    EndSync = definition of step in script at which to wait for synchronization

Right now, I am adding a "Random" command to this list, that will randomly pick from a selected group of actions to take, whether a single group move or a command (i.e., "Playscript") to play a sequence. That way, Peter can loop his actions and not do the same thing every time.

Also, once Peter has sensors added, the software will include conditional execution and the scripting commands will by definition become a true programming language. One other option is to use the program to generate code for one or more of the microprocessors Lynxmotion sells.


Attachment:
Animatron.bas [10.71 KiB]
Downloaded 151 times

_________________
Heard in the workshop: PEBRAC...
User avatar
Guru ( offline )
Posts: 3298
Posted: 2010-12-14 14:18 
this is a nice way of executing movement. nice work. :wink:

i like the "random" feature. looking to use something like this in my project.

_________________
Jonny Poole,
Freelance Concept Art & Animatronics, 3D Art and 3D Modelling, as well as Physical Modelling, Mechanical design, and illustration.
http://www.innerbreed.co.uk
Create, Innovate, Inspire.


User avatar
Guru ( offline )
Posts: 2120
Posted: 2010-12-14 17:03 
Great work!

djsfantasi wrote:
The feature of being able to define multiple scripts is similar to having two GP players available on the SSC-32, only you can define more than two series of commands to execute in parallel (well, kinda in parallel… More like alternating commands from different scripts and using the delay time in the moves to execute other moves - timesharing). On my penguin, I can have one script moving the head, a second script moving the arms and a third script controlling the torso.


That is a pretty neat feature. I would guess this work only as long as the scripts doesn't involve the same servo?

Thanks for sharing your code! :D

_________________
Kåre Halvorsen, Zenta
-----------------------------------------
Zenta's blog
http://zentasrobots.com/
Zenta's YouTube channel
http://www.youtube.com/ZentaOlbaid
-----------------------------------------


User avatar
Expert ( offline )
Posts: 293
Posted: 2010-12-14 19:05 
It is written with the expectation that the multiple scripts would not use the same servo. If you did, the results would be unexpected as the scripts running in parallel would fight over control. Thinking about it, using the SyncPoint and EndSync commands, it might be possible for parallel scripts to cooperate. Theoretically of course. I'll have to test that. :wink:

_________________
Heard in the workshop: PEBRAC...


User avatar
Guru ( offline )
Posts: 4116
Posted: 2010-12-14 21:22 
The random mode is good, you might also want to consider reading some sensors, such as proximity (a person is near), temperature, light (maybe he nods off when the lights drop!), etc. Basically, a shift in behaviors due to stimuli.

Maybe Peter likes a little sprinkle of water!

Alan KM6VV

_________________
Visit:
http://groups.yahoo.com/group/SherlineCNC/
http://tech.groups.yahoo.com/group/HexapodRobotIK/


User avatar
Expert ( offline )
Posts: 293
Posted: 2010-12-15 12:40 
Once Peter has sensors added, the software will include conditional execution and the scripting commands will by definition become a true programming language. Then he will react to his surroundings. Perhaps even eventually be able to respond to voice with appropriate responses.

Peter would probably like more than a "sprinkle" of water - more like a dive! Perhaps I can add an olfactory sensor so he can react when he smells mackerel :wink:

_________________
Heard in the workshop: PEBRAC...


Guru ( offline )
Posts: 2251
Posted: 2010-12-15 13:01 
Below is a talking bird.

http://www.shopgadgetsandgizmos.com/product/2319/

_________________
Why I like my 2005 rio yellow Honda S2000 with the top down, and more!
http://youtube.com/watch?v=pWjMvrkUqX0
http://youtube.com/watch?v=qfyRA-g1nhI
http://web.comporium.net/~shb/S2000video.htm


User avatar
Guru ( offline )
Posts: 9258
Posted: 2010-12-15 13:26 
zoomkat wrote:
Below is a talking bird.


That's the stupidest thing I've seen in a long time.

_________________
Jim Frye, the Robot Guy
http://www.lynxmotion.com
I've always tried to do my best...


Guru ( offline )
Posts: 2251
Posted: 2010-12-15 14:01 
Quote:
That's the stupidest thing I've seen in a long time.


Yes, but under the right circumstances even stupid sells.

_________________
Why I like my 2005 rio yellow Honda S2000 with the top down, and more!
http://youtube.com/watch?v=pWjMvrkUqX0
http://youtube.com/watch?v=qfyRA-g1nhI
http://web.comporium.net/~shb/S2000video.htm


User avatar
Expert ( offline )
Posts: 293
Posted: 2011-01-01 19:49 
I was able to get the random movement programming done in my Animatron basic program. Peter has been doing his own thing beside me while I type this description for you all. Here is my test script that has been running...

Code:
Startscript,Main,0
Label,DoItAgain,0
RandomMove,Head Fakes,12
Playmove,Look ahead,500
Playmove,Look right,500
Playmove,Look left,500
Playmove,Look right slowly,1500
Playmove,Look ahead slowly,1500
Playmove,Look left slowly,1500
Playmove,Face Right,500
Playmove,Face Forward,500
Playmove,Face Left,500
Playmove,Face Right Slow,2000
Playmove,Face Forward Slow,2000
Playmove,Face Left Slow,2000
JumpTo,DoItAgain,0
Endscript,Main,0


It was not too difficult to fit the logic into the structure of the existing program. Defining the command 'RandomMove" was similar to the SyncPoint, EndSync and Scriptpause commands; that is I only needed to define the action and a single value.

RandomMove only needs to know how many different commands it can select from when making a choice. It then uses a random number generator to pick one of them to execute next, and sets the script's pointer to that command. The trick was to resume execution AFTER the block of commands (repeating the random selection process was easy, as the program already had a 'Label' and 'JumpTo' command). In order to do this, RandomMove also calculates the next step after the defined block of possible moves.

I defined a state variable that was then used when selecting the next command to execute. There are three defined states: No need to adjust the next step, within the random selection, so execute the current step, but set the state so that NEXT time, the command after the defined block of moves is executed.

Right now, the moves are purely random. The sample script I have included just moves his head and eyes back and forth -- but it is enjoyable to see Peter move on his own - i.e. unscripted.
A current code listing follows...

Code:
#include once "windows.bi"
#include once "win/mmsystem.bi"
'      ===========================================================================
'      ===========================================================================
'      ===========================================================================
'      ===========================================================================

Declare Function FindIt (array() As String, What As String) As Integer
Declare Function DisplayStep (i As Integer, j As Integer) As String

ReDim MoveDescription(0) As String ' Move lookup table: description of move, e.g. "Move Eyes Left"
ReDim MoveCommand(0) As String ' actual servo move command, e.g. "#0P2000 #1P2000 T100"
Dim MoveIndex As Integer =0 ' array index of Move arrays

ReDim LabelDescription(0) As String   ' Label lookup table; name of label or script
ReDim LabelScriptIndex(0) As Integer ' index to step after label in script arrays
Dim LabelIndex As Integer =0 ' array index for Label arrays

ReDim PlayerStep(0) As Integer      ' Player properties: index to step in script to execute next
ReDim As Double PlayerEndWait(0)      ' array of time before next command is issued, by player
PlayerEndWait(0)=0
Dim As Double SoundEndWait=0         ' timer value before next check of ADC for voice/sound input, ~12ms from last test.
Dim Player As Integer =0

ReDim ScriptAction(0) As Integer   ' Script properties: action to take
ReDim ScriptDescription(0) As Integer ' Index to servo move table
ReDim ScriptOption(0) As Integer ' value for action, i.e. pause length after command is issued
Dim ScriptStep As Integer =0, MainScript As Integer =0
Dim ErrorFound As Integer =0

' Properties for executing a random move from a selection of 'n' commands
' also, can be used for other non-linear execution plans for a script.
Const NoAdjustStepAction = 1 ' constant values to indicate the state of processing a random move
Const InRandomSelection  = 2
Const AdjustStepAction   = 3
ReDim As Integer AdjustStep(0) ' state variable for adjusting the step
                                               ' while processing a random move
Dim As Integer Selections ' variable to store the possible number of random moves from which to select
ReDim As Integer NextStep(0)   ' variable which will point to the step AFTER a random move block
Randomize

ReDim SyncPoints(0) As ULongInt ' flags for sync points; bit encoded by associated players
Dim SyncPointStatus As ULongInt =0
Dim SyncPointIndex As Integer =0

Dim IndexPlayers As Integer = 0, MaxPlayers As Integer =0, NotDone As Integer =-1 ' script player definitions

'Speech variables
Dim As String dat, ssc32cmd, PW, qs, cr
Dim As Integer level
Dim soundFile As String

'Control variables
Dim As String ControlKey
Dim SingleStep As Integer = 0
Const PauseKey="\"
Const Esc = Chr(27)

'SSC-32 constants
Const scbase="#3P"
qs = "VA" + Chr(13)
cr = Chr(13)

' Prepare Show
Dim CommPort As String  ' serial port connected to servo controller (SSC-32)
Dim Animatron As String ' name of file containing mapping between move descriptions and SSC-32 commands
Dim ShowName As String  ' name of file containing a script for a given "show"
Const dfltCommPort = "com4:"
Const dfltMoves = "peter.csv"
Const dfltScript = "Peter-Live.csv"

' connection to servo controller (SSC-32)
Print "Comm port [";dfltCommPort;"]: ";
Input CommPort
If CommPort = "" Then CommPort = dfltCommPort

' short description to servo controller (SSC-32) commands mappings
Print "Character/Move file name [";dfltMoves;"]:";
Input Animatron
If Animatron = "" Then Animatron = dfltMoves
Open Animatron For Input As #1

' script file
Print "Show file name [";dfltScript;"]: ";
Input ShowName
If ShowName = "" Then ShowName = dfltScript

'      ===========================================================================
'      ===========================================================================
'       Define Moves (lookup table)
'      ===========================================================================
'      ===========================================================================

' read in short description and corresponding SSC-32 command
Dim Move As String , CtrlrCmd As String
Do While Not Eof(1)And ErrorFound =0
   Input #1, Move, CtrlrCmd
   If UCase(Move) = "END" Then Exit Do 
   MoveIndex += 1
   ReDim Preserve MoveDescription(MoveIndex)As String, MoveCommand(MoveIndex)As String
   MoveDescription(MoveIndex) = Move
   MoveCommand(MoveIndex) = CtrlrCmd+cr      
Loop
Close #1



'      ===========================================================================
'      ===========================================================================
'       Define Script(s)
'      ===========================================================================
'      ===========================================================================

Open ShowName For Input As #1

Dim Action As String, Description As String, OptionValue As Integer, LocalIndex As Integer
Const PlayMove As Integer     =0 ' send commands to SSC-32
Const PlayScript As Integer =1 ' execute script in parallel; script must be defined in same file
Const StartScript As Integer=2 ' define new script; main script MUST be last in file
Const EndScript As Integer  =3 ' end of script routine definition
Const JumpTo As Integer     =4 ' "goto" command; label MUST exist (is not checked for)
Const Label As Integer        =5 ' definition of label used in "JumpTo" command
Const SyncPoint As Integer  =6 ' definition of scripts which will synchronize with other script(s)
Const EndSync As Integer     =7 ' definition of step in script at which to wait for synchronization
Const ScriptPause As Integer=8 ' "Pause" or "Delay" command; pauses execution for n milliseconds
Const Say As Integer=9 ' play external sound file; will cause servo defined in "scbase" (e.g. mouth servo) to synchronize to sound
Const RandomMove As Integer=10 ' Randomly perform on of the following 'n' actions; n is the option value

Do While Not Eof(1) And ErrorFound =0
   Input #1, Action, Description, OptionValue
   Print Action, Description, OptionValue
   
   Select Case UCase(Action)
      
      Case "PLAYMOVE"
         ScriptStep +=1
         ReDim Preserve ScriptAction(ScriptStep), ScriptDescription(ScriptStep), ScriptOption(ScriptStep)
         ScriptAction(ScriptStep) = PlayMove
         LocalIndex = FindIt(MoveDescription(), Description)
         If LocalIndex < 0 Then
            Print "Cannot find move ";Description
            ErrorFound=1
            Exit Do
         Else
            ScriptDescription(ScriptStep) = LocalIndex
         EndIf
         ScriptOption(ScriptStep) = OptionValue
      
      Case "STARTSCRIPT", "LABEL"
         LabelIndex +=1
         ReDim Preserve LabelDescription(LabelIndex) As String, LabelScriptIndex(LabelIndex)As Integer
         LabelDescription(LabelIndex) = Description
         LabelScriptIndex(LabelIndex)=ScriptStep+1
         If UCase(Action) = "STARTSCRIPT" Then MainScript=ScriptStep+1
         
      Case "PLAYSCRIPT", "JUMPTO"
         ScriptStep+=1
         ReDim Preserve ScriptAction(ScriptStep) As Integer, ScriptDescription(ScriptStep) As Integer, ScriptOption(ScriptStep) As Integer
         If UCase(Action) = "PLAYSCRIPT" Then
            ScriptAction(ScriptStep)=PlayScript
         Else
            ScriptAction(ScriptStep)=JumpTo
         EndIf
         LocalIndex = FindIt(LabelDescription(), Description)
         If LocalIndex < 0 Then
            Print "Cannot find script or label ";Description
            ErrorFound=2
            Exit Do
         Else
            ScriptDescription(ScriptStep) = LabelScriptIndex(LocalIndex)
         EndIf
      
      Case "SAY"
         LabelIndex +=1
         ReDim Preserve LabelDescription(LabelIndex) As String, LabelScriptIndex(LabelIndex)As Integer
         LabelDescription(LabelIndex) = Description
         LabelScriptIndex(LabelIndex)=ScriptStep+1
         ScriptStep +=1
         ReDim Preserve ScriptAction(ScriptStep) As Integer, ScriptDescription(ScriptStep) As Integer, ScriptOption(ScriptStep) As Integer
         ScriptAction(ScriptStep) = Say
         ScriptDescription(ScriptStep) = LabelIndex

      Case "ENDSCRIPT"
         ScriptStep +=1
         ReDim Preserve ScriptAction(ScriptStep) As Integer, ScriptDescription(ScriptStep) As Integer, ScriptOption(ScriptStep) As Integer
         ScriptAction(ScriptStep) = EndScript
         
      Case "SYNCPOINT", "ENDSYNC", "SCRIPTPAUSE", "RANDOMMOVE"
         ScriptStep+=1
         ReDim Preserve ScriptAction(ScriptStep) As Integer, ScriptDescription(ScriptStep) As Integer, ScriptOption(ScriptStep) As Integer
         If UCase(Action)="SYNCPOINT" Then
            If OptionValue>SyncPointIndex Then SyncPointIndex=OptionValue
            ScriptAction(ScriptStep)=SyncPoint
         ElseIf UCase(Action)="ENDSYNC" Then
            ScriptAction(ScriptStep)=EndSync
         ElseIf  UCase(Action)="RANDOMMOVE" Then
            ScriptAction(ScriptStep)=RandomMove
         Else
            ScriptAction(ScriptStep)=ScriptPause
         EndIf
         ScriptDescription(ScriptStep)=OptionValue
         ScriptOption(ScriptStep)=OptionValue

      Case Else
         Print "Unrecognized script command"
         ErrorFound=4
         Sleep
         Exit Do          

   End Select
Loop

Close #1
If ErrorFound Then End ErrorFound


'      ===========================================================================
'      ===========================================================================
'       Execute processed Script(s)
'      ===========================================================================
'      ===========================================================================

If timeBeginPeriod( 1 ) = TIMERR_NOCANDO Then
  Print "Specified period is out of range"
  ErrorFound=3
End If
If ErrorFound Then End ErrorFound

Open Com CommPort+" 115200,N,8,1,BIN,CD,CS,DS,RS" For Binary As #1
If Err Then
   Print "Could not open ";CommPort
EndIf

' initialize sound subsystem
Put #1,,qs
Sleep 12
dat=Input$(Loc(1),#1)

' define first step
MaxPlayers=0
ControlKey=""
PlayerStep(MaxPlayers) = MainScript
AdjustStep(MaxPlayers)=NoAdjustStepAction
ReDim SyncPoints(SyncPointIndex) As ULongInt

Print "Starting to play script at ";Mainscript
Print UBound(ScriptAction);" steps in script"
Print
Print "Press any key to start";
Sleep
ControlKey=InKey

Print ""
Print "Press <\> key to pause, <Any> key to resume,"
Print "<Enter> to enter/leave single step mode,"
Print "<Space> to step through script,"
Print "<Esc> key to stop execution and leave the program."
   Print "3..."
   Sleep 1000
   Print "2..."
   Sleep 1000
   Print "1..."
   Sleep 1000
   Print "!"
   ControlKey="x"

   Do While ControlKey <> ""
      ControlKey=InKey
      Sleep 1
   Loop

Do While NotDone ' "NotDone" is true until the main script executes an "EndScript" command
   For Player=0 To MaxPlayers ' "Player = 0" is the main script


' Speech processing ...
      If (SoundEndWait-Timer <0) Then
         dat = Input$(Loc(1), #1)

         If dat = "" Then
            ' Print "No data"
         Else
            level = Asc(dat)
            ' Print "Level ";level
            Select Case level
               Case 0 To 12
                  PW="600"
               Case 13 To 25
                  PW="700"
               Case 25 To 255
                  PW="800"
            End Select
      
            ssc32cmd=scbase+PW+cr
            'Print "Command = ";ssc32cmd
            Put #1,, ssc32cmd
         End If

         Put #1,,qs
         SoundEndWait=Timer+.012
      EndIf
      
      
      If ((PlayerEndWait(Player)-Timer)< 0) And (PlayerStep(Player)<>0) Then
         PlayerEndWait(Player)=0
         Select Case AdjustStep(Player)
            Case NoAdjustStepAction
               ScriptStep=PlayerStep(Player)
            Case InRandomSelection
               ScriptStep=PlayerStep(Player)
               AdjustStep(Player)=AdjustStepAction
            Case AdjustStepAction
               PlayerStep(Player)=NextStep(Player)
               ScriptStep=NextStep(Player)
               AdjustStep(Player)=NoAdjustStepAction
         End Select
         
      ' Pause/Single Step script on request
      ControlKey=InKey
      If ControlKey = PauseKey Then
         Print "Script paused per request"
         Sleep
         Print "Continuing..."
      ElseIf ControlKey = cr Then
         SingleStep = Not SingleStep
      ElseIf ControlKey = Esc Then
         NotDone=0
         Exit For
      EndIf
      If SingleStep Then
         Print "Single ";
         Sleep
      EndIf


      
         Select Case ScriptAction(ScriptStep)
            
            Case PlayMove
               MoveIndex=ScriptDescription(ScriptStep)
               Print "Step ";DisplayStep(Player,ScriptStep);":  ";MoveDescription(MoveIndex),MoveCommand(MoveIndex)
               Put #1,,MoveCommand(MoveIndex)
               PlayerEndWait(Player)=Timer+ScriptOption(ScriptStep)/1000
               PlayerStep(Player)=ScriptStep+1

            Case ScriptPause
               Print "Step ";DisplayStep(Player,ScriptStep);":  ";
               Print Using "Pause #.###";(ScriptOption(ScriptStep)/1000)
               PlayerEndWait(Player)=Timer+ScriptOption(ScriptStep)/1000
               PlayerStep(Player)=ScriptStep+1

            Case PlayScript
               IndexPlayers=1
               Do While IndexPlayers <= MaxPlayers
                  If PlayerStep(IndexPlayers)=0 Then Exit Do
                  IndexPlayers+=1
               Loop
               If IndexPlayers>MaxPlayers Then
                  MaxPlayers+=1
                  ReDim Preserve PlayerStep(MaxPlayers) As Integer, PlayerEndWait(MaxPlayers) As Double
                  ReDim Preserve As Integer AdjustStep(MaxPlayers), NextStep(MaxPlayers)
               EndIf
               PlayerStep(IndexPlayers)=ScriptDescription(ScriptStep)
               PlayerEndWait(IndexPlayers)=0
               AdjustStep(IndexPlayers)=NoAdjustStepAction
               PlayerStep(Player)=ScriptStep+1
               Print "Step ";DisplayStep(Player,ScriptStep);":  Starting script on Player ";IndexPlayers
               
            Case EndScript
               PlayerStep(Player)=0
               NotDone = (Player<>0) ' main script has ended
               Print "Step ";DisplayStep(Player,ScriptStep);":  Scripts have completed on ";Player

            Case JumpTo
               Print "Step ";DisplayStep(Player,ScriptStep);":  Jump to";ScriptDescription(ScriptStep)
               PlayerStep(Player)=ScriptDescription(ScriptStep)
               
            Case SyncPoint
               SyncPointIndex=ScriptDescription(ScriptStep)
               Print "Step ";DisplayStep(Player,ScriptStep);":  Defining synchronization point ";SyncPointIndex
               If Player > 63 Then
                  Print "Too many simultaneous Players...";Player
                  Exit Do
               EndIf
               SyncPoints(SyncPointIndex)=SyncPoints(SyncPointIndex) Or (2^Player)
               PlayerStep(Player)=ScriptStep+1
               
            Case EndSync
               SyncPointIndex=ScriptDescription(ScriptStep)
               If Player > 63 Then
                  Print "Too many simultaneous Players...";Player
                  Exit Do
               EndIf
               SyncPointStatus= SyncPoints(SyncPointIndex) And (Not 2^Player)
               If SyncPointStatus <> SyncPoints(SyncPointIndex) Then
                  Print "Step ";DisplayStep(Player,ScriptStep);":  Sync'ing to";SyncPointIndex;"  [";SyncPoints(SyncPointIndex);"]"
               EndIf
               SyncPoints(SyncPointIndex)= SyncPointStatus
               If SyncPoints(SyncPointIndex) = 0 Then
                  PlayerStep(Player)=ScriptStep+1
               EndIf

            Case RandomMove
               Selections=ScriptDescription(ScriptStep)
               NextStep(Player)=ScriptStep+Selections+1
               MoveIndex=Int(Rnd()*Selections)+1
               PlayerStep(Player)=ScriptStep+MoveIndex
               AdjustStep(Player)=InRandomSelection
               Print "Step ";DisplayStep(Player,ScriptStep);":  RandomMove of";Selections
            
            Case Say
               soundFile=LabelDescription(ScriptDescription(ScriptStep))
               Print "Step ";DisplayStep(Player,ScriptStep);":  Saying ";soundFile
               PlaySound(soundFile, NULL, SND_ASYNC Or SND_FILENAME)
               PlayerStep(Player)=ScriptStep+1
            
         End Select
      EndIf
      
   Next
   Sleep 1
Loop

timeEndPeriod( 1 )
Print "Press any key to finish";
Print
Sleep

End

Function FindIt (AnArray() As String, What As String) As Integer
   Dim i As Integer
   For i=0 To UBound(AnArray)
      If AnArray(I) = What Then Exit For
   Next
   If i > ubound(AnArray) Then i=-16384
   Return i
End Function

Function DisplayStep(i As Integer, j As Integer) As String
   Dim Display_Number As String =""
   Display_Number = Right("  " & Str(i),2) & "-"+Left(Str(j) & "   ",3)
   Return Display_Number
End Function

Edit 1-5-11: updated code after some bug fixes; the random selection can now successfully call other scripts and has been tested with up to six scripts/players running in parallel. Had to limit the number of players/simultaneous scripts to 64; more than the amount of servos available, so is not a limit practically! Also changed the display to show the player AND step being executed...


Attachment:
Animatron2.zip [4.21 KiB]
Downloaded 95 times

_________________
Heard in the workshop: PEBRAC...
User avatar
Expert ( offline )
Posts: 293
Posted: 2011-01-19 22:03 
The RandomMove command was so successful, I added a RandomPause command. When running multiple scripts, sometimes it seemed as if Peter had had too much coffee :shock: . A pause command added to the random move selection helped, but a random pause command made his actions less predictable.

Hope to have a new video this weekend; still tweaking my show script.

Also, code has been added to accept commands over a TCP socket, in preparation for connecting an iPhone. I just need to parse the command like the pre-processor section of code does, in order to send the results to the SSC-32. Initially, it will accept just play move and play script commands from the iPhone or a telnet client. I can use the latter to test and also control Peter from another computer in the house. (If I had a fixed public IP address, he could be controlled over the Internet as well :idea: ...)

_________________
Heard in the workshop: PEBRAC...


Guru ( offline )
Posts: 2251
Posted: 2011-01-20 02:12 
Quote:
(If I had a fixed public IP address, he could be controlled over the Internet as well ...)


Dynamic ip services like below can fix that problem. I use the no-ip service.

http://www.no-ip.com/services/managed_d ... c_dns.html
http://www.dyndns.com/services/dns/dyndns/

_________________
Why I like my 2005 rio yellow Honda S2000 with the top down, and more!
http://youtube.com/watch?v=pWjMvrkUqX0
http://youtube.com/watch?v=qfyRA-g1nhI
http://web.comporium.net/~shb/S2000video.htm


User avatar
Expert ( offline )
Posts: 293
Posted: 2011-01-23 22:12 
Thanks to zoomkat, I connected with dyndns.org.

After configuring my router, my son was able to use his iPad and control Peter over the Internet. 8)

Way cool

_________________
Heard in the workshop: PEBRAC...


1, 2

All times are UTC - 5 hours [ DST ]. It is currently 2014-09-02 12:42
Feedback Form
Feedback Form