Roller coaster Application Code

And while I’m posting code, here’s the application code.  Just plain ol’ posix C, grabbing a serial port for output the old fashioned way.  If you just want to see the results, scroll about two posts down to the video.  THAT was fun to make.

Next post, I’ll put up the text file that I used for the roller coaster you see in the video.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TABLE_SIZE 255
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */





int main(int argc, char *argv[]) {
  int pipefds1[2];
  int pipefds2[2];
  int child;
  int i, buffercount=0;
  double video_progression=0;
  char fan[MAX_TABLE_SIZE];
  float trigger[MAX_TABLE_SIZE];
  char axis[MAX_TABLE_SIZE];
  char position[MAX_TABLE_SIZE];
  int table_size;
  char checksum;
  char speed[MAX_TABLE_SIZE];
  int action_step=0;
  float start,end;
  char coaster_name[10];
  FILE * fin;
  char tmp[200];
  char commandstring[100];
  char * pch;
  char * dch;

  switch (argc)
  {
    case 2:
        if ((fin = fopen(argv[1], "r")) == NULL)
        {
            /* First string (%s) is program name (argv[0]). */
            /* Second string (%s) is name of file that could */
            /* not be opened (argv[1]). */
            (void)printf("%s: Cannot open input file %s\n", argv[0], argv[1]);
            return(2);
        }
        break;
    default:
        printf("Usage: %s [file]\n", argv[0]);
        return(2);
  }

  // display what we've just read
  while(fin!=NULL && fgets(tmp, sizeof(tmp), fin)!=NULL)
  { //look for certain key words and grab the number
      // THEN if it's not a key word parse the control line
        pch = strstr(tmp, "START:");
        if (pch)
            {
                start=atof(pch + 6);
            }
        else
        {
            pch = strstr(tmp, "END:");
            if (pch)
                {
                    end=atof(pch + 4);
                }
            else
            {
                pch = strstr(tmp, "NAME:");
                if (pch)
                    {
                        strcpy(coaster_name,pch + 5);
                    }
                else //well, we're not name, end or start
                {

                    if (!(strstr(tmp, "#")) && strstr(tmp, " "))
                    { // looks like we've got a line of data
                        //printf(tmp);
                        dch = strtok (tmp," ");
                        if (dch != NULL)
                            { // first get the trigger time
                                trigger[buffercount]=atof(dch);
                                dch = strtok (NULL, " ");
                                axis[buffercount]=atoi(dch);
                                dch = strtok (NULL, " ");
                                position[buffercount]=atoi(dch);
                                dch = strtok (NULL, " ");
                                speed[buffercount]=atoi(dch);
                                dch = strtok (NULL, " ");
                                fan[buffercount]=atoi(dch);
                        //Troubleshooting debug type code
                                /*printf ("%f ",trigger[buffercount]);
                                printf ("%c ",axis[buffercount]);
                                printf ("%d ",position[buffercount]);
                                printf ("%d ",speed[buffercount]);
                                printf ("%d\n",fan[buffercount]);*/
                            }
                        buffercount++;
                    }
                }
            }
        }
  }
  table_size=buffercount;
  //printf("Start is:%f End is:%f Name is:%s \n",start,end,coaster_name);
  fclose(fin);
  pipe(pipefds1);
  pipe(pipefds2);
  child = fork();
  close(pipefds1[!!child]);
  close(pipefds2[!child]);
  if (!child) {
    dup2(pipefds1[1], 1);
    dup2(pipefds2[0], 0);
    execlp("mplayer", "mplayer", "-slave", "-quiet", "-fs", "raw_6_steel.mp4", NULL);
  }
  else
  {
    char buf[1000];
    char command_out[10] = "~";
    char timebuf[8];
    int r;
    sprintf(commandstring, "seek %f\n",start);
    write(pipefds2[1], commandstring, strlen(commandstring));
    sleep(1);
    write(pipefds2[1], "get_time_pos\n", 13);
    // new stuff
    int fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
      if (fd == -1)
      {
       /*
 * Could not open the port.
 */
      }
    struct termios options;

    /*
     * Get the current options for the port...
     */

    tcgetattr(fd, &options);

    /*
     * Set the baud rates to 115200...
     */

    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);


// 8N1
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

// no hw flow control
    options.c_cflag &= ~CRTSCTS;
    /*
     * Enable the receiver and set local mode...
     */

    options.c_cflag |= (CLOCAL | CREAD);

    /*
     * Set the new options for the port...
     */


    tcsetattr(fd, TCSANOW, &options);


    // end of new stuff
    while ((r = read(pipefds1[0], buf, 1000)) > 0) {
      buf[r] = 0;
      if (strstr(buf,"ANS_TIME_POSITION"))
      {
        for (i=0; i<6; i++)
        {
          timebuf[i]=buf[i + 18];
          if (timebuf[i-1]==46)
          {
              timebuf[i+1]=0;
              i=9;  //big enough to get out of the for loop
          }
        }
        video_progression=atof(timebuf);
        if (video_progression > end)
            write(pipefds2[1], "quit\n", 13);
        //printf("MPlayer out: %f\n", video_progression);
        if (video_progression > trigger[action_step])
        {
            if((action_step == 0) || ((action_step > 0) && (trigger[action_step] > trigger[action_step - 1])))
            {
                checksum=0;
                printf("~");
                printf ("%x",axis[action_step]);
                command_out[1]=axis[action_step];
                checksum+= axis[action_step];
                printf ("%x",position[action_step]);
                command_out[2]=position[action_step];
                checksum+= position[action_step];
                printf ("%x",speed[action_step]);
                command_out[3] = speed[action_step];
                checksum+= speed[action_step];
                printf ("%x",fan[action_step]);
                command_out[4] = fan[action_step];
                checksum+= fan[action_step];
                printf ("%x\n",checksum);
                command_out[5]=(char)checksum;
                write(fd, command_out, 6 );
                action_step++;
            }
        }
      //sleep(1);
      }
      write(pipefds2[1], "get_time_pos\n", 13);

    }
  }
  return 0;
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s