void ttCreatePeriodicTask(char *name, double offset, double period, double priority, double (*codeFcn)(int, void*), void* data) {
  
  DataNode *n;

  if (ttCreatePeriodicTask(name, offset, period, priority, codeFcn)) {
    n = (DataNode*) rtsys->taskList->getLast();
    ((Task*) n->data)->data = data;
  }
}
Example #2
0
void init()
{
  // Initialize TrueTime kernel
  ttInitKernel(1, 0, prioFP); // nbrOfInputs, nbrOfOutputs, fixed priority

  // Sensor task
  double offset = 0.0;
  double period = 0.010;
  double prio = 1.0;
  ttCreatePeriodicTask("sensor_task", offset, period, prio, sensor_code);

  // Initialize network
  ttCreateInterruptHandler("msgRcv", prio, msgRcvhandler);
  ttInitNetwork(4, "msgRcv"); // node #4 in the network
}
Example #3
0
void init() {

  // Read the input argument from the block dialogue
  mxArray *initarg = ttGetInitArg();
  if (!mxIsDoubleScalar(initarg)) {
    TT_MEX_ERROR("The init argument must be a number!\n");
    return;
  }
  int implementation = (int)mxGetPr(initarg)[0];

  // Allocate KernelData memory and store pointer in kernel
  KernelData *kd = new KernelData;
  ttSetUserData(kd);

  // Allocate memory for implementation != 2
  TaskData *d = new TaskData;
  kd->d = d;  // Store pointer in KernelData

  // Allocate memory for implementation 2
  double *d2 = new double;
  kd->d2 = d2; // Store pointer in KernelData

  // Allocate memory for implementation 4
  int *hdl_data = new int;
  kd->hdl_data = hdl_data;   // Store pointer in KernelData
  
  // Initialize TrueTime kernel
  ttInitKernel(prioFP);

  // Task attributes
  double starttime = 0.0;
  double period = 0.006;
  double deadline = period;

  // Controller parameters and states
  d->K = 0.96;
  d->Ti = 0.12;
  d->Td = 0.049;
  d->beta = 0.5;
  d->N = 10.0;
  d->h = period;
  d->u = 0.0;
  d->t = 0.0;  // only used for implementation 3
  d->Iold = 0.0;
  d->Dold = 0.0;
  d->yold = 0.0;
  d->rChan = 1;
  d->yChan = 2;
  d->uChan = 1;

  switch (implementation) {
    
  case 1:
    // IMPLEMENTATION 1: using the built-in support for periodic tasks
    
    ttCreatePeriodicTask("pid_task", starttime, period, pid_code1, d);
    
    break;

  case 2:
    // IMPLEMENTATION 2: calling Simulink block within code function
    
    ttCreatePeriodicTask("pid_task", starttime, period, pid_code2, d2);
    break;

  case 3:
    // IMPLEMENTATION 3: sleepUntil and loop back
  
    ttCreateTask("pid_task", deadline, pid_code3, d);
    ttCreateJob("pid_task");
    break;
    
  case 4:
    // IMPLEMENTATION 4: sampling in timer handler, triggers task job
  
    *hdl_data = 2; // y_chan for reading samples
    ttCreateHandler("timer_handler", 1, sampler_code, hdl_data);
    ttCreatePeriodicTimer("timer", starttime, period, "timer_handler");
    ttCreateMailbox("Samples", 10);
    ttCreateTask("pid_task", deadline, pid_code4, d);
    break;

  }
}
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
  rtsys = getrtsys() ; // Get pointer to rtsys 
  if (rtsys==NULL) {
    return;
  }

  // Check number and type of arguments. 
  if (nrhs < 5 || nrhs > 6) {
    MEX_ERROR("ttCreatePeriodicTask: Wrong number of input arguments! \nUsage: ttCreatePeriodicTask(name, offset, period, priority, codefcn)\n       ttCreatePeriodicTask(name, offset, period, priority, codefcn, data)");
    return;
  }

  if (mxIsChar(prhs[0]) != 1) {
    MEX_ERROR("ttCreatePeriodicTask: name must be a string");
    return;
  }
  if (!mxIsDoubleScalar(prhs[1])) {
    MEX_ERROR("ttCreatePeriodicTask: offset must be a double scalar");
    return;
  }
  if (!mxIsDoubleScalar(prhs[2])) {
    MEX_ERROR("ttCreatePeriodicTask: period must be a double scalar");
    return;
  }
  if (!mxIsDoubleScalar(prhs[3])) {
    MEX_ERROR("ttCreatePeriodicTask: priority must be a double scalar");
    return;
  }
  if (mxIsChar(prhs[4]) != 1 || mxGetM(prhs[4]) != 1) {
    MEX_ERROR("ttCreatePeriodicTask: codeFcn must be a non-empty string");
    return;
  }
  
  char name[100];
  mxGetString(prhs[0], name, 100);

  double offset = *mxGetPr(prhs[1]);
  if (offset < -EPS) {
    offset = 0.0;
    printf("ttCreatePeriodicTask: negative offset changed to zero\n");
  }
  
  double period = *mxGetPr(prhs[2]);

  double priority = *mxGetPr(prhs[3]);

  char codeFcn[100];
  mxGetString(prhs[4], codeFcn, 100);

  // Make sure that the code function exists in Matlab path
  mxArray *lhs[1];
  mxArray *rhs[1];
  rhs[0] = mxDuplicateArray(prhs[4]);
  mexCallMATLAB(1, lhs, 1, rhs, "exist");
  int number = (int) *mxGetPr(lhs[0]);
  if (number == 0) {
    char buf[200];
    sprintf(buf, "ttCreatePeriodicTask: codeFcn '%s' not in path! Task '%s' not created!", codeFcn, name);
    MEX_ERROR(buf);
    return;
  }

  if (ttCreatePeriodicTask(name, offset, period, priority, NULL)) {

    // Add name of code function (m-file) and data variable
    DataNode *n = (DataNode*) rtsys->taskList->getLast();
    UserTask *usertask = (UserTask*) n->data;
    
    usertask->codeFcnMATLAB = new char[strlen(codeFcn)+1];
    strcpy(usertask->codeFcnMATLAB, codeFcn);
    
    mxArray* data;
    if (nrhs == 5) { // no data specified
      data = mxCreateDoubleMatrix(0, 0, mxREAL);
    } else {
      data = mxDuplicateArray((mxArray*)prhs[5]);
    }
    mexMakeArrayPersistent(data);
    usertask->dataMATLAB = data;
  }
}