Converting Sequencer Data To Useable Stuff?

I’ve been having trouble with getting the playlog.txt to show me the entirety of what I need.

When I play the entire program (with the “P>” button), the log contains:

Pausing : 260 Pausing : 260 Pausing : 510 Pausing : 510 Pausing : 510 Pausing : 510 Pausing : 510 Pausing : 510 Pausing : 510 Pausing : 1000 Pausing : 1000 Pausing : 1000 Pausing : 1000 Pausing : 1000 Pausing : 1000 Pausing : 510 Pausing : 510 Pausing : 510 Pausing : 510

And that’s with 4 sequences.

If i’m not mistaken, that’s just the time that each servo is taking to move to it’s new position.

I need the positions themselves.

When I play a single sequence, I get this:

Pausing : 510 Pausing : 510 Pausing : 510 Pausing : 510

Is this supposed to be happening?

After puttering around for a while with that, I tried a different method.

I exported the project and converted it to a text file.
Then I edited out the unecessary parts.
Then I renamed it as a .txt file so that I could access it with VBE.NET

The following is the code that I tried, followed by a comment which shows what the .txt file looks like:

[code]Imports System

Imports System.IO

Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

ReadFromFile()

End Sub

Private Sub ReadFromFile()

Dim letter, word, line, WholeLine As String

Dim LetterCount, WordCount, LineCount, TimingCount As Integer

Dim position(LineCount, WordCount)

Dim timing(LineCount, TimingCount)

Using sr As StreamReader = New StreamReader(“C:\ServoPositionsAndTiming.txt”)

Do

LineCount += 1

LetterCount = 0

WordCount = 0

TimingCount = 0

line = Nothing

WholeLine = sr.ReadLine()

Do

LetterCount += 1

letter = sr.Read()

line &= letter

If letter <> “;” Then

word &= letter

End If

If letter = “;” Then

WordCount += 1

If WordCount > LineCount * 38 And WordCount < LineCount * 38 + 20 Then

position(LineCount, WordCount) = CSng(word)

word = Nothing

TextBox1.Text &= position(LineCount, WordCount)

End If

If WordCount > LineCount * 38 + 19 And WordCount < LineCount * 38 + 39 Then

TimingCount = WordCount - 19

timing(LineCount, TimingCount) = CSng(word)

word = Nothing

TextBox1.Text &= timing(LineCount, TimingCount)

End If

End If

Loop Until letter = line

Loop Until letter = “z”

sr.Close()

End Using

End Sub

Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged

End Sub

End Class

‘’’’’'This is exactly what the file that I’m reading is, except for the apostrophe’s, of course:

‘’’’’'PIN0;PIN1;PIN2;PIN3;PIN4;PIN12;PIN13;PIN14;PIN15;PIN16;PIN17;PIN18;PIN19;PIN20;PIN24;PIN28;PIN29;PIN30;PIN31;T0;T1;T2;T3;T4;T12;T13;T14;T15;T16;T17;T18;T19;T20;T24;T28;T29;T30;T31

‘’’’’’-10.8;7.5;-18;26.129;-28.286;90;3.12;90;38.4;26.182;3;24.646;-13.2;38;6.429;-90;-11.793;90;-49.355;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510

‘’’’’’-10.8;7.5;-18;26.129;-28.286;90;3.12;90;38.4;26.182;3;24.646;-13.2;38;-69.686;1.277;-46.924;90;24.039;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510

‘’’’’’-10.8;7.5;-18;26.129;-28.286;90;3.12;90;38.4;26.182;3;24.646;-13.2;38;6.429;-90;-11.793;90;-49.355;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510

‘’’’’’-10.8;7.5;-18;26.129;-28.286;-3.84;3.361;90;6.36;26.182;3;24.646;-13.2;38;77.271;-90;-11.421;90;-49.355;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510

‘’’’’'z[/code]

Apparently, I messed something up, because when I debug, the Form never loads.

So, something up there is infinitely executing.

Does anyone know a better way to use the Sequencer’s positioning data, without having to go and edit every single one?

I can point out a couple things that look like they behaving differently than you might be expecting.

WholeLine = sr.ReadLine()
letter = sr.Read()

There is a position pointer in the stream that is incremented every time you read. So letter will contain the first character after the line read into WholeLine

Do Loop Until letter = line will match the first time through.

Your reinventing the wheel a bit with your cutom word tokenizing code. Check out the string.Split method.

Oh, sweet, string.split is exactly what I need.

Now, I can use the ReadLine method, which I’m much more comfortable with.

Ahh, yes, I should have used Peek, like I do in QB.
I was forgetting that Readline would move the cursor.

Sigh… I’m hopeless.

I can’t get the split method to work.

[code]Private Sub SplitString()
Dim a As String = “-10.8;7.5;-18;26.129;-28.286;90;3.12;90;38.4;26.182;3;24.646;-13.2;38;6.429;-90;-11.793;90;-49.355;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;-10.8;7.5;-18;26.129;-28.286;90;3.12;90;38.4;26.182;3;24.646;-13.2;38;-69.686;1.277;-46.924;90;24.039;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;-10.8;7.5;-18;26.129;-28.286;90;3.12;90;38.4;26.182;3;24.646;-13.2;38;6.429;-90;-11.793;90;-49.355;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;-10.8;7.5;-18;26.129;-28.286;-3.84;3.361;90;6.36;26.182;3;24.646;-13.2;38;77.271;-90;-11.421;90;-49.355;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510”

    Dim i As Integer
    Dim array(i)
    For i = 0 To UBound(array)
        array(i) = a.Split(";")
        Debug.WriteLine(array(i))
    Next
End Sub[/code]

The only thing that’s in the immediate window is “System.String]”.

I’m starting to realize just how different QB and VB are…

.<"

Oh, I just caught a mistake…

Dim array(i) needs to be changed to Dim array (38 * 4)

But, all I get out of it now is 38 * 4 repetitions of “System.String]”.

:unamused:

it’s even easier than that. You don’t have to know the size.

It returns an array of strings that is sized based upon the data you pass it. So you can now iterate through the array and convert the values to singles if you like:
(I’m a bit unfamiliar with the VB syntax, so here’s the c#)

String] array;

array = YourString.Split(';');

foreach (String s in array)
    Debug.WriteLine(Single.Parse(s).ToString());

//or another way to iterate a bit closer to the manner you were attempting

for (int i = 0; i < array.length; i++)
    Debug.WriteLine(Single.Parse(array*).ToString());

I’m converting to a single and back to a string only for illustrative purposes.*

Hmm…
I really wish that I had seen that last night.
:stuck_out_tongue:

I spent the day remaking the program.
I still have to stick it into a GUI, trigger everything by events, and generalize the code so that I can turn it into a function.
But, I figured that I’d paste what I have here, now that (I believe) I have it working.
When I put in a loop to print the serial into a textbox, it comes out as the proper syntax.
Although, I’m not sure if I did the “pause” correctly.
I know that QBasic will attempt to continually execute a loop that has nothing in it, but VB may not.
I haven’t tested it on the biped, yet, because he’s charging, but I’ll get back to you guys when I get the chance.

If anyone’s interested, feel free to steal any/all of this for whatever you’d like.

[code]Imports System
Imports System.IO

Public Class Form1

Dim substring As String
Dim individualvalue(3, 63), stepdegree(31) As Single
Dim position(3, 31), speed(3, 31) As Integer
Dim syntax(3) As String

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    ReadFromFile()
    StepDegrees()
    Conversion()
    AssembleSyntax()
    SendToSSC32()
End Sub


Private Sub ReadFromFile()
    Dim i, j As Integer
    'Open up the file using the StreamReader function.
    Using sr As StreamReader = New StreamReader("C:\ComboPunch.txt")
        'Split the entire file up into multiple substrings.
        'Each substring is contained between two of the following characters:
        'semicolon, space, or nothing
        Dim file As String() = sr.ReadToEnd.Split(New [Char]() {";", " ", Nothing})
        For Each substring In file
            If substring.Trim <> ";" Then                   'These take out the
                If substring.Trim <> " " Then               'unwanted characters in the
                    If substring.Trim <> Nothing Then       'split-up strings.
                        'Convert each split-up string into
                        'a single floating-point number.
                        individualvalue(i, j) = CSng(substring)
                        j += 1
                        'At the end of every line, go to the next array dimension.
                        If j = 64 Then
                            i += 1
                            j = 0
                        End If
                    End If
                End If
            End If
        Next
        'Close the file
        sr.Close()
    End Using
End Sub 'Form1


Private Sub StepDegrees()
    'You can find these on the SSC-32 page of the Visual Sequencer.
    stepdegree(0) = 0.18
    stepdegree(1) = 0.15
    stepdegree(2) = 0.138
    stepdegree(3) = 0.116
    stepdegree(4) = 0.129
    stepdegree(12) = 0.12
    stepdegree(13) = 0.121
    stepdegree(14) = 0.116
    stepdegree(15) = 0.12
    stepdegree(16) = 0.164
    stepdegree(17) = 0.15
    stepdegree(18) = 0.116
    stepdegree(19) = 0.12
    stepdegree(20) = 0.133
    stepdegree(24) = 0.129
    stepdegree(28) = 0.116
    stepdegree(29) = 0.124
    stepdegree(30) = 0.116
    stepdegree(31) = 0.116
End Sub 'StepDegrees


Private Sub Conversion()
    Dim i, j, k As Integer
    For i = 0 To 3
        For j = 0 To 63
            'The first 32 in each dimension are position values.
            If j < 32 Then
                'Convert it to an integer for speedier sending.
                '(There's no reason not to round it off once the math is done.)
                position(i, j) = CInt(individualvalue(i, j) / stepdegree(k) + 1500)
            End If
            'The next 32 in each dimension are speed values.
            If j > 31 Then
                'Make it so that there's no index offset between speed and position.
                'Convert it to an Integer for speedier sending.
                speed(i, k) = CInt(individualvalue(i, j))
                k += 1
            End If
        Next j
        k = 0
    Next i
End Sub 'Conversion


Private Sub AssembleSyntax()
    Dim i, j As Integer
    For i = 0 To 3
        For j = 0 To 31
            'Stick the position and speed into the SSC-32's proper syntax.
            syntax(i) &= "#" & j & "P" & position(i, j) & "S" & speed(i, j) & " "
        Next j
        'Send a carriage return after every complete set of servo positioning.
        syntax(i) &= vbCrLf
    Next i
End Sub 'AssembleSyntax


Private Sub SendToSSC32()
    Dim i, j As Integer
    Dim pause As Double
    'Open the port for sending.
    SerialPort4.Open()
    For i = 0 To 3
        'Send each set of servo positioning seperately.
        SerialPort4.Write(syntax(i))
        'Set the pause time between sendings for 510 milliseconds.
        pause = Microsoft.VisualBasic.DateAndTime.Timer + 0.51
        'Do nothing during that time.
        Do Until Microsoft.VisualBasic.DateAndTime.Timer > pause
        Loop
    Next i
    'Close the port once finished sending.
    SerialPort4.Close()
End Sub

End Class

‘’’’‘Example text file to be read:
‘’’’‘There are no apostrophes (comment marks) in the actual file.
‘’’’‘When editing your own files, be sure to put a ; before each line.
‘’’’‘If you neglect to do so,the last number of the preceeding line will get smushed with ‘’’’‘the first number of that line [example: 510-10.8 ].
‘’’’’;-10.8;7.5;-18;26.129;-28.286;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;90;3.12;90;38.4;26.182;3;24.646;-13.2;38;3.58E-6;3.58E-6;3.58E-6;6.429;3.58E-6;3.58E-6;3.58E-6;-90;-11.793;90;-49.355;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510
‘’’’’;-10.8;7.5;-18;26.129;-28.286;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;90;3.12;90;38.4;26.182;3;24.646;-13.2;38;3.58E-6;3.58E-6;3.58E-6;-69.686;3.58E-6;3.58E-6;3.58E-6;1.277;-46.924;90;24.039;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510
‘’’’’;-10.8;7.5;-18;26.129;-28.286;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;90;3.12;90;38.4;26.182;3;24.646;-13.2;38;3.58E-6;3.58E-6;3.58E-6;6.429;3.58E-6;3.58E-6;3.58E-6;-90;-11.793;90;-49.355;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510
‘’’’’;-10.8;7.5;-18;26.129;-28.286;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;3.58E-6;-3.84;3.361;90;6.36;26.182;3;24.646;-13.2;38;3.58E-6;3.58E-6;3.58E-6;77.271;3.58E-6;3.58E-6;3.58E-6;-90;-11.421;90;-49.355;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510;510[/code]

your pause looks like it will probably work but it’s what is called a Busy Wait and is generally shunned in a multiprocessing OS like windows. It means that you’re consuming 100% of the CPU for the duration of that loop instead of going to sleep and being notified when the time is up.

A more multitasking friendly way of doing that is

System.Threading.Thread.Sleep(510);

One other thing: I’m not positive, but I think split is going to remove the chars you are splitting on. So the further test for those three chars is unnecessary. Also, “nothing” isn’t a char and I don’t this is having any effect on the Split.

Nice!
Your pause is much easier, too.

Ahhh, thanks, Andy.
I didn’t think that they would, but a bit of overkill doesn’t hurt when you don’t know what your doing.

:stuck_out_tongue:

I’ll replace the Nothing with “” an kill the unecessary decisions.

Thanks.

^.^

a “” (empty string) isn’t going to do anything either. What are you trying to do by including it?

I was trying to make sure that empty storage spaces would not be put into the arrays.

It was actually not doing anything, though, because when i tried that same code on another text file, it didn’t manage to keep ""s out of the array.

Do you know of any method for that?

your empty string elements are found between the delimiting chars. So if you have “1 ;2” you’ll get a 3 element array {1, empty, 2}

If you’re not interested in spaces (I don’t see any in your sample data), just filter them out before the split with a replace()

Hi there,

about the playlog.txt bug,
can you send to me the exported csv file project ?

i will try to figure what’s the problem, i can’t make the bug occur here.

I’m afraid that I don’t still have the original csv file, but there’s great news…

For some reason, the playlog.text started showing the actual positioining, as well as the timing, when I checked it.
Now, I’ve been able to impliment the SSC-32 code directly, via the good ol’ copy & paste into an array.

Besides, my translation algorithm from degrees to pulse value was a bit off for some of the servos (probably had to with my not changing the max and min degree when i changed the max and min pulses, when I initially set up the sequencer).

Ahh, thanks, Andy.
I tried replacing in that other program, and it works wonders.
:smiley:

Here’s my final code:
I killed all the buttons, and went for strictly key inputs, because it’s hard to use a mouse while watching the robot, anyhow.

[code]
Imports System
Imports System.IO

Public Class Form1
Dim servoposition(30) As String

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    ServoPositions()
End Sub

Private Sub ServoPositions()
    'Stand
    servoposition(0) = "#0P1440#1P1550#2P1420#3P1700#4P1180#5P1500#6P1500#7P1500#8P1500#9P1500#10P1500#11P1500#12P2150#13P1530#14P2250#15P1820#16P1510#17P1620#18P1720#19P1340#20P1860#21P1500#22P1500#23P1500#24P1550#25P1500#26P1500#27P1500#28P700#29P1380#30P700#31P1050T510"

    'Walk
    servoposition(1) = "#0P1676#3P1704#4P1075#13P1550#16P1621#17P1580#18P1680#19P1300#29P1056#31P1333T510"
    servoposition(2) = "#0P1535#1P1339#2P1413#3P1464#4P1180#13P1827#15P1532#16P1668#28P1006#29P1380#31P1224T1000"
    servoposition(3) = "#0P1479#1P1204#2P1761#3P1682#4P1232#13P1785#16P1652#17P1541#18P1559#19P1123#20P1984#28P1180#31P1268T1000"
    servoposition(4) = "#0P1380#4P1075#13P1550#15P1820#16P1544#20P1851#31P1030T1000"
    
    'Well, you get the idea...
End Sub

Private Sub MoveBiped(ByVal start As Integer, ByVal finish As Integer, ByVal pausetime As Integer)
    Dim i, j As Integer
    'Open the port for sending.
    TextBox1.Text = ""
    SerialPort4.Open()
    For i = start To finish
        'Send each set of servo positioning seperately.
        SerialPort4.Write(servoposition(i) & vbCrLf)
        'Display each servo position for aid in debugging.
        TextBox1.Text &= (servoposition(i) & vbCrLf)
        'Pause between each step for a given amount of time.
        System.Threading.Thread.Sleep(pausetime)
    Next i
    'Close the port once finished sending.
    SerialPort4.Close()
    'Display the servo positions for aided debugging.
End Sub

Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged
    Dim key As String
    Dim start, finish As Integer
    key = TextBox2.Text
    Select Case key
        Case Is = "i"
            'UP
            start = 1
            finish = 7
            Dim pausetime As Integer = 510
            MoveBiped(start, finish, pausetime)
        Case Is = "k"
            'DOWN
            start = 0
            finish = 0
            Dim pausetime As Integer = 510
            MoveBiped(start, finish, pausetime)
        Case Is = "j"
            'LEFT
            start = 18
            finish = 21
            Dim pausetime As Integer = 510
            MoveBiped(start, finish, pausetime)
        Case Is = "l"
            'RIGHT
            start = 13
            finish = 17
            Dim pausetime As Integer = 510
            MoveBiped(start, finish, pausetime)
        Case Is = "f"
            'THRUST
            start = 26
            finish = 28
            Dim pausetime As Integer = 510
            MoveBiped(start, finish, pausetime)
        Case Is = "d"
            'COMBO
            start = 8
            finish = 11
            Dim pausetime As Integer = 510
            MoveBiped(start, finish, pausetime)
        Case Is = "s"
            'SWEEP
            start = 0
            finish = 0
            Dim pausetime As Integer = 510
            MoveBiped(start, finish, pausetime)
        Case Is = "a"
            'BACKHAND
            start = 22
            finish = 25
            Dim pausetime As Integer = 510
            MoveBiped(start, finish, pausetime)
        Case Is = "1"
            'FIGHTING STANCE
            start = 11
            finish = 11
            Dim pausetime As Integer = 510
            MoveBiped(start, finish, pausetime)
        Case Is = "2"
            'NORMAL STANCE
            start = 0
            finish = 0
            Dim pausetime As Integer = 510
            MoveBiped(start, finish, pausetime)
    End Select
    TextBox2.Text = ""
End Sub

End Class[/code]

By the way, when I execute and press a button to send a sequence, the pause isn’t working the way that I’d like to.

Instead of displaying the text at each iteration of the loop (and thus showing me exactly which sequence I’ve messed up :stuck_out_tongue:), it seems to be storing it all in a buffer and displaying it after the loop is finished.

I stepped through the execution, and this seems to be the case.
But, when i checked in the “help” (yea, that’s a laugh) file, they don’t mention anything about textbox buffers, or have any commands that seem to apply.

Is there any way to override this buffer and display it in real time?

read about DoEvents()