1. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Download Package Now!
  2. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  3. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant here. Do not following these rules will lead to permanent exclusion from this website: Read the forum rules.

Question Soft starting motion platforms?

Discussion in 'SimTools Pro & Entertainment Version' started by Zed, Oct 20, 2017.

  1. Brett Horton

    Brett Horton Active Member Gold Contributor

    Joined:
    Aug 18, 2016
    Messages:
    289
    Occupation:
    UAS Manager / Pilot / Integration Specialist
    Location:
    Tampa FL
    Balance:
    40Coins
    Ratings:
    +191 / 2 / -0
    My Motion Simulator:
    3DOF, DC motor, JRK, Motion platform
    Thanks Zed, I corrected the mistake
  2. noorbeast

    noorbeast VR - The Next Generation Staff Member Moderator

    Joined:
    Jul 13, 2014
    Messages:
    13,778
    Occupation:
    Innovative tech specialist for NGOs
    Location:
    St Helens, Tasmania, Australia
    Balance:
    103,713Coins
    Ratings:
    +8,611 / 42 / -2
    My Motion Simulator:
    3DOF, DC motor, JRK
    • Like Like x 3
  3. Zed

    Zed VR Simming w/Index

    Joined:
    Apr 4, 2017
    Messages:
    793
    Location:
    USA
    Balance:
    4,286Coins
    Ratings:
    +812 / 3 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    No problem and thanks again on the video and testing! I hope to sort the device identifier thing soon and will update when I get that plus maybe make it do a semi-arbitrary number of axes, more error checking, etc. :thumbs
    • Like Like x 1
    Last edited: Oct 22, 2017
  4. Zed

    Zed VR Simming w/Index

    Joined:
    Apr 4, 2017
    Messages:
    793
    Location:
    USA
    Balance:
    4,286Coins
    Ratings:
    +812 / 3 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    I’m glad it’s useful and it really was purely selfish. I wanted this for myself.

    I do plan on improving it a bit more but no hurry since this will work for most applications. Brett noted that he doesn’t really need a third axis even though he has traction loss. He’s always centered up well when he shuts down. It’s just the seat axes that sag down. We'll see. If anyone needs more than two axes, I can certainly add them.

    Thanks for maintaining all this stuff here. And also glad to give back. Brett and I were talking about just what a trip all this is that we can do this and especially in VR. Years ago I’d see stuff something like the motion platforms but nowhere near as good, and never thought I’d have my own and be able to drive, fly, ride rollercoasters, etc, all in VR. This place is a huge resource. So thanks, again. :thumbs
    • Agree Agree x 3
    • Like Like x 1
  5. Zed

    Zed VR Simming w/Index

    Joined:
    Apr 4, 2017
    Messages:
    793
    Location:
    USA
    Balance:
    4,286Coins
    Ratings:
    +812 / 3 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    Hey all - favor to ask if someone has a proper compiler.

    This program works every time for me but only about 30% of the time for Brett and not at all for Mirko. I built the executable using MinGW. It's a minimalist version of GCC and is a C compiler that has a Windows version. I used MinGW since it is what Pololu used to build their examples with in the JRK manual.

    I think it is hanging in the system call to the USB port from the reports I get from Brett and Mirko but I don't know for sure. The program is really simple though. The JRKs are up and running and can be queried for feedback values (arm positions) even with the H-bridge output off. It takes command line arguments for a "step" value (basically speed - lower value = slower - it's the increment used each time it outputs a new position) and the comm port values for two JRKs. It reads the scaled feedback values since those are universal and in 0-4095 value space and then writes those same feedback values out since the position is also in 0-4095. Writing the values out also automatically turns on the JRK H-bridge output. There may be some noise in the feedback value read where the position commanded isn't necessarily the actual arm position, but it's close enough. There are no big jerks or bangs. The program then iterates from those initial positions to the midpoint value of 2048 incrementing or decrementing as need be using the step value each time. When it gets to the midpoint, the program ends. That's all it does.

    But with the oddness of writing to the USB ports sometimes hanging - I think that's what it is but am not 100% sure - it doesn't always work on some systems. Anyone have a full-fledged compiler and willing to give it a go?

    Here is the source code as the program is now. Note that usleep is depricated and you may need to use a different delay.

    Anyone up to try it? I think Brett and Mirko would be happy. Not my best coding but I was just trying to get it to work. If anyone has questions, feel free to ask and I'll see what I can do. Looks like the BBS software trampled the formatting. Sorry...

    // Uses POSIX functions to send and receive data from a jrk.
    // NOTE: The jrk's input mode must be "Serial".
    // NOTE: The jrk's serial mode must be set to "USB Dual Port".
    // NOTE: You must change the 'const char * device' line below.

    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <time.h>

    #ifdef _WIN32
    #define O_NOCTTY 0
    #else
    #include <termios.h>
    #endif

    char version[10] = "0.2b";

    // Reads a variable from the jrk.
    // The 'command' argument must be one of the two-byte variable-reading
    // commands documented in the "Variable Reading Commands" section of
    // the jrk user's guide.

    int jrkGetVariable(int fd, unsigned char command)
    {
    if(write(fd, &command, 1) == -1)
    {
    perror("error writing");
    return -1;
    }

    unsigned char response[2];
    if(read(fd,response,2) != 2)
    {
    perror("error reading");
    return -1;
    }
    return response[0] + 256*response[1];
    }

    // Gets the value of the jrk's Feedback variable (0-4095).
    int jrkGetFeedback(int fd)
    {
    return jrkGetVariable(fd, 0xA5);
    }

    // Gets the value of the jrk's Scaled Feedback variable (0-4095).
    int jrkGetScaledFeedback(int fd)
    {
    return jrkGetVariable(fd, 0xA7);
    }

    // Gets the value of the jrk's Target variable (0-4095).
    int jrkGetTarget(int fd)
    {
    return jrkGetVariable(fd, 0xA3);
    }

    // Sets the jrk's Target variable (0-4095).
    int jrkSetTarget(int fd, unsigned short target)
    {
    unsigned char command[] = {0xC0 + (target & 0x1F), (target >> 5) & 0x7F};
    if (write(fd, command, sizeof(command)) == -1)
    {
    perror("error writing"); return -1;
    }
    return 0;
    }

    int main(int argc, char *argv[])
    {

    printf("Home vers. %s\n", version);

    // Validate inputs
    printf("Inputs = %d.\n", argc);
    if (argc != 4)
    {
    printf("Usage is home.exe <step size> <com1> <com2> eg: home.exe 2 COM4 COM7\n");
    return -1;
    }

    printf("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);

    int step = atoi(argv[1]);
    if ((step < 1) || (step > 10))
    {
    step = 1;
    }

    printf("Using step size of %d.\n", step);

    // Open the 1st Jrk's virtual COM port.
    char dev1[10];
    char dev2[10];

    sprintf (dev1, "\\\\.\\%s", argv[2]);
    sprintf (dev2, "\\\\.\\%s", argv[3]);

    const char * device1 = dev1;
    int fd1 = open(device1, O_RDWR | O_NOCTTY);
    if (fd1 == -1)
    {
    perror(device1);
    return 1;
    }

    // Open the 2nd Jrk's virtual COM port.
    const char * device2 = dev2;
    int fd2 = open(device2, O_RDWR | O_NOCTTY);
    if (fd2 == -1)
    {
    perror(device2);
    return 1;
    }

    #ifndef _WIN32
    struct termios options;
    tcgetattr(fd, &options);
    options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    options.c_oflag &= ~(ONLCR | OCRNL);
    tcsetattr(fd, TCSANOW, &options);
    #endif

    int sfeedback1 = jrkGetScaledFeedback(fd1);
    printf("Current Scaled Feedback1 is %d.\n", sfeedback1);

    int sfeedback2 = jrkGetScaledFeedback(fd2);
    printf("Current Scaled Feedback2 is %d.\n", sfeedback2);

    int setting1 = jrkGetTarget(fd1);
    printf("Old Setting1 is %d.\n", setting1);

    int setting2 = jrkGetTarget(fd2);
    printf("Old Setting2 is %d.\n", setting2);

    // Starting positions
    int target1 = sfeedback1;
    int target2 = sfeedback2;

    int final1 = 2048;
    int final2 = 2048;

    int working1 = 1;
    int working2 = 1;
    while ((working1 == 1) || (working2 == 1))
    {
    if (target1 > final1)
    {
    target1 -= step;
    jrkSetTarget(fd1, target1);
    printf("Target1 is %d.\n", target1);
    if (target1 <= final1)
    {
    jrkSetTarget(fd1, final1);
    working1 = 0;
    }
    }
    else
    {
    target1 += step;
    jrkSetTarget(fd1, target1);
    printf("Target1 is %d.\n", target1);
    if (target1 >= final1)
    {
    jrkSetTarget(fd1, final1);
    working1 = 0;
    }
    }

    if (target2 > final2)
    {
    target2 -= step;
    jrkSetTarget(fd2, target2);
    printf("Target2 is %d.\n", target2);
    if (target2 <= final2)
    {
    jrkSetTarget(fd2, final2);
    working2 = 0;
    }
    }
    else
    {
    target2 += step;
    jrkSetTarget(fd2, target2);
    printf("Target2 is %d.\n", target2);
    if (target2 >= final2)
    {
    jrkSetTarget(fd2, final2);
    working2 = 0;
    }
    }
    usleep (5);
    }

    setting1 = jrkGetTarget(fd1);
    printf("New Setting1 is %d.\n", setting1);

    setting2 = jrkGetTarget(fd2);
    printf("New Setting2 is %d.\n", setting2);

    close(fd1);
    close(fd2);

    printf("Done!\n");

    return 0;
    }
    • Like Like x 2
  6. gSeat

    gSeat Member

    Joined:
    Oct 1, 2017
    Messages:
    107
    Location:
    usa
    Balance:
    908Coins
    Ratings:
    +48 / 0 / -0
    Amazing @Zed thank you, found this by accident while traversing pololu's site for power info
    :cheers
  7. Zed

    Zed VR Simming w/Index

    Joined:
    Apr 4, 2017
    Messages:
    793
    Location:
    USA
    Balance:
    4,286Coins
    Ratings:
    +812 / 3 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    @gSeat - please let me know how it works for you. @Brett Horton has had some problems with it on his rig. It seems to hang and not sure why. Sometimes it works and sometimes it doesn’t.
    • Agree Agree x 1
  8. Zed

    Zed VR Simming w/Index

    Joined:
    Apr 4, 2017
    Messages:
    793
    Location:
    USA
    Balance:
    4,286Coins
    Ratings:
    +812 / 3 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    Just an update. We may be onto why Brett's rig stalls. Will post updates and maybe a new executable if we are indeed getting it sorted.
    • Like Like x 1
  9. katikomer

    katikomer New Member Gold Contributor

    Joined:
    Nov 12, 2016
    Messages:
    8
    Occupation:
    Marine Engineer
    Location:
    NZ
    Balance:
    126Coins
    Ratings:
    +5 / 0 / -0
    My Motion Simulator:
    2DOF, JRK, Motion platform
    Hi mate

    is this compatible with WIN10? I keep getting the error in command prompt that this app cant run on this PC. You come across this before?

    Thanks
  10. Zed

    Zed VR Simming w/Index

    Joined:
    Apr 4, 2017
    Messages:
    793
    Location:
    USA
    Balance:
    4,286Coins
    Ratings:
    +812 / 3 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    I wrote it on Win 10. Not sure what’s causing the message for you. I don’t get that message.

    Also, one thing to keep in mind and it’s kind of a Catch 22. The JRK has a regular operating region which SimTools uses for motion but this utility is meant to bring the platform to center from its at-rest position which is almost always going to be outside of the normal operating range unless you block the platform to keep it from moving out of the normal range. In the JRK setup you can use a different, generally lower, max pulse width when the motors are outside of the normal range. That value needs to be enough that the motors can still move the platform almost normally or else the pulse width will go from the low value to normal operating when the motor positions move inside the normal range. If the commanded position is enough ahead of the actual, the pulse width can wind way up and slam the platform instead of soft starting.

    I’ve been thinking about this issue and how to fix it and the only thing I can come up with is setting the max pulse width when outside of range to the same value as inside of range of the soft start, then setting it back to its previous value once the soft start completes. The problem with that is it means extra and frequent writes to the JRK EEPROM which can wear it out and kill the JRK controller so it’s not a good solution.

    That makes the next best solution the one we need to go with. You need to set the maximum pulse width in the JRK setup utility when outside the normal operating range high enough that the commanded platform position can be followed close enough that the actual position isn’t so far behind the command that when it gets inside the normal operating range the pulse width doesn’t go max and slam the platform. Or else always block the platform so when powered off it stays within the normal operating range.

    What we need is a special motion command where the max pulse width can be specified in the command so the EEPROM doesn’t get worn out by repeated reprogramming.

    Hope this helps. I was having my platform slam occasionally until I realized this is what was going on and increased the max pulse width setting when outside the normal operating range. The problem is that that setting is there as a safety valve so that if the position goes outside of normal limits, forces are reduced to minimize damage. To use this utility means adding some force back in. It’s probably much less an issue on seat shakers as the necessary forces are less. I’ve got a full-frame that is out of balance a bit when I’m not on it so it needs some extra force to bring it to center when I’m not in position.
    • Like Like x 1
    • Informative Informative x 1
  11. Bord-Ing.

    Bord-Ing. New Member

    Joined:
    Sep 17, 2016
    Messages:
    25
    Location:
    South Germany
    Balance:
    349Coins
    Ratings:
    +17 / 0 / -0
    Hm, just a keen guess: Another app has opened the COM port before and your program just want to do the same, but can't. So your prog waits until it gets a timeout which can be a longer timespan, depending on the default timeout configuration. But this could behave like the program hangs up.


    But maybe it's totally nonsense I tell :D
  12. Zed

    Zed VR Simming w/Index

    Joined:
    Apr 4, 2017
    Messages:
    793
    Location:
    USA
    Balance:
    4,286Coins
    Ratings:
    +812 / 3 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    That’s a very reasonable thought but I can center my rig with or without SimTools running and it works fine. Obviously this is before I launch an app as that is where we get the hard core full force centering this whole exercise is meant to stop.

    I don’t think USB has the same restrictions on opening and holding a com port as programs used to have since we can plug hubs in that have lots of devices hanging off them. The computer just has the one port for a hub but multiple apps need to write to the devices. I think in that respect, USB has some network-like features where you write to an address and the devices sort things out - even if the device itself is addressed as a com port.

    And that may also be hooey, but I do know I can center my rig whether SimTools is also running or not, and if I remember correctly also while the JRK utility is up and also communicating with the controller.