// controller code function
double ctrl_code(int seg, void *data)
{
  double *m;
  double r, y, P, D;
  PD_Data* d = (PD_Data*) data;

  switch(seg) {
  case 1:
    ttTake("sem"); // wait for a message
    return 0.0;

  case 2:
    m = (double*) ttGetMsg(); // get sensor value
    y = *m;
    delete m; // delete message
    r = ttAnalogIn(1);
    
    P = d->K*(r-y);
    D = d->ad*d->Dold + d->bd*(d->yold-y);
    d->u = P + D;
    d->Dold = D;
    d->yold = y;
    return 0.0005;

  case 3:
    m = new double;
    *m = d->u;
    ttSendMsg(2, m, 80); // Send 80 bits to node 2 (actuator)
    ttSetNextSegment(1); // loop and wait for new packet
    return 0.0;
  }

  return FINISHED; // to supress compilation warnings
}
示例#2
0
void *ttGetMsg() {
  if (rtsys->nbrOfNetworks == 0) {
    TT_MEX_ERROR("ttGetMsg: The node is not connected to to any network!");
    return NULL;
  }
  if (rtsys->nbrOfNetworks > 1) {
    TT_MEX_ERROR("ttGetMsg: The node is connected to more than one network - specify which!\n");
    return NULL;
  }
  int network = rtsys->networkInterfaces[0].networkNbr;  // find first (and only) network number
  return ttGetMsg(network);
}
示例#3
0
/**	Task, executed upon receiving a network message
 * on the I2C-bus.
 */
double msg_rcv_handler(int seg, void* t_d)
{
  AODVrcv_Data *d = (AODVrcv_Data *) t_d;
  MailboxMsg *mailboxmsg;
  DataMsg *dataMsg;
  
  generic *m;
  m = (generic *) ttGetMsg(I2C_NETWORK + d->bot_nbr - 1);
  switch (seg) {
  case 1:
    switch (m->t){
      // Forwarding velocity references from Mega_128 to wheel avr:s
      // or forwarding velocities from wheel avr:s to Mega_128.
    case SEND_WHEEL_VEL:
      {
	if (((SEND_WHEEL_VEL_MSG*) m->msg)->hdr.sender == MEGA_128) {
	  if (((SEND_WHEEL_VEL_MSG*) m->msg)->hdr.receiver == LEFT_WHEEL)
	    ttSendMsg(I2C_NETWORK + d->bot_nbr - 1, LEFT_WHEEL, m, 8+32);
	  else
	    ttSendMsg(I2C_NETWORK + d->bot_nbr - 1, RIGHT_WHEEL, m, 8+32);
	} else { // This else needs to be modified
	  mailboxmsg = new MailboxMsg;
	  dataMsg = new DataMsg;
	  dataMsg->data = ((SEND_WHEEL_VEL_MSG*) m->msg)->vel;
	  mailboxmsg->datamsg = dataMsg;
	  ttPost("WheelRequestBox",mailboxmsg);
	  //   ttSendMsg(I2C_NETWORK + d->bot_nbr - 1, MEGA_128, m, 10);
	  delete m;
	}
	
	return 0.0001;
      }
      
      // Forwarding obstacle avoidance information from Mega_Ultra to
      // to Mega_128.
    case SEND_IR:
      {
	ttSendMsg(I2C_NETWORK + d->bot_nbr - 1, MEGA_128, m, 8+32);
	return 0.0001;
      }

    default: {}

    }

    
    return 0.0001;
    
  default:
    return FINISHED;
  }
}
示例#4
0
double AODVrcvcode(int seg, void* data) {
  AODVrcv_Data* d = (AODVrcv_Data*) data;
  int myID = d->nodeID;
  
  MailboxMsg *mailboxmsg;
  GenericNwkMsg *nwkmsg;
  DataMsg *datamsg;
  RREQMsg *rreqmsg;
  RREPMsg *rrepmsg;
  RERRMsg *rerrmsg, *rerrmsg2;
  HelloMsg *hellomsg;
  
  int i, dest, seqNbr, hopCnt, cond1, cond2;
  int intermed, drop, cached_RREQID, propagate, nextHop;
  double now, etime1, etime2, lifetime;
  double etime = 0.0001;
  
  RouteEntry *dest_entry, *src_entry;
  DataNode *dn;
  
  switch (seg) {
    case 1:
      nwkmsg = (GenericNwkMsg*) ttGetMsg(ZIGBEENETW);
      now = ttCurrentTime();
      
      ///////////////////////
      // Tmote stuff start //
      ///////////////////////
      if(nwkmsg->type == RANGE_RESPONSE) {
        if (ttCurrentTime() < d->rcv_timeout) {
          // Get data from rangeResponseMsg and then delete it
          RangeResponseMsg *rangeResp = (RangeResponseMsg *)nwkmsg->msg;
          
          double x, y;
          unsigned int range;
          
          range = rangeResp->range;
          x = rangeResp->x;
          y = rangeResp->y;
          
          d->responseCounter++;
          //		mexPrintf("Response counter = %d \n",d->responseCounter);
          
          // Remove 145 for 2ms delay
          // Add 80 for compensation for unknown error
          double dist;
          //   	dist = 34400.0 * (double)(range - 145 + 80) / 72280.0; original
          dist = 34400.0 * (double)(range - 145 + 68) / 72280.0;
          //		dist = 34400.0 * (double)(range - 145) / 72280.0;
          //		mexPrintf("Distance measurment from %d = %f \n",rangeResp->nodeID,dist);
          
          // Put values in data
          d->node_x = x;
          d->node_y = y;
          d->node_dist = dist;
          // DEBUG
          d->node_nodeID = rangeResp->nodeID;
          if (fabs(dist) < 300.0) {
            // Start task that sends data to mega128
            ttCreateJob("node_data_to_kalman");
          }
        }
      } else if (nwkmsg->type == RANGE_REQUEST) {
        d->snd_block = ttCurrentTime() + 0.310;
      }
      //////////////////////
      // Tmote stuff ends //
      //////////////////////
      else if (nwkmsg->type == DATA) {
        // Data message
        datamsg = (DataMsg*) nwkmsg->msg;
        delete nwkmsg;
        
        if (datamsg->dest == myID) {
          // Data message arrived at destination
          if (VERBOSE) {
            mexPrintf("Time: %f Data message arrived at Node#%d\n", now, myID);
          }
          
          // Update expiry timer for route to source
          d->routing_table[datamsg->src - 1].exptime = now + ACTIVE_ROUTE_TIMEOUT;
          
          // Notify application
          ttTryPost("AODVRcvBox", datamsg);
          ttCreateJob("RcvTask");
          
          etime = 0.0001;
        } else {
          // Forward data message
          if (VERBOSE) {
            mexPrintf("Time: %f Node#%d about to forward data to Node#%d Data: %f\n", now, myID, datamsg->dest, datamsg->data);
          }
          
          // Update expiry timer for route to source
          d->routing_table[datamsg->src - 1].exptime = now + ACTIVE_ROUTE_TIMEOUT;
          
          // Find route to destination and update expiry timer
          dest_entry = &(d->routing_table[datamsg->dest - 1]);
          dest_entry->exptime = now + ACTIVE_ROUTE_TIMEOUT;
          
          // Forward data message to next hop
          nwkmsg = new GenericNwkMsg;
          nwkmsg->type = DATA;
          nwkmsg->msg = datamsg;
          ttSendMsg(1, dest_entry->nextHop, nwkmsg, datamsg->size);
          
          etime = 0.0001;
        }
        updateExpiryTimer(d->routing_table, d->dataTimer, myID);
      } else {
        // AODV control message (RREQ, RREP, RERR, or HELLO)
        if (VERBOSE) {
          mexPrintf("Time: %f Node#%d processing AODV message type: %d from Node#%d\n", now, myID, nwkmsg->type, nwkmsg->intermed);
        }
        
        switch (nwkmsg->type) {
          case RREQ:
            rreqmsg = (RREQMsg*) nwkmsg->msg;
            intermed = nwkmsg->intermed;
            
            if (rreqmsg->src == myID) {
              // Skip RREQs received by the original source
              
              etime = 0.00001;
            } else {
              // Have this RREQ already been processed?
              cached_RREQID = d->cache[rreqmsg->src - 1];
              
              drop = 0;
              if (rreqmsg->RREQID <= cached_RREQID) {
                // Found in cache, drop redundant RREQ
                if (VERBOSE) {
                  mexPrintf("Time: %f Node#%d dropping redundant RREQ from Node#%d\n", now, myID, intermed);
                }
                drop = 1;
              }
              
              if (!drop) {
                // process RREQ
                if (VERBOSE) {
                  mexPrintf("Time: %f Node#%d caching RREQ with Src: %d RREQID: %d\n", now, myID, rreqmsg->src, rreqmsg->RREQID);
                }
                
                // Enter RREQID in cache
                d->cache[rreqmsg->src - 1] = rreqmsg->RREQID;
                
                // Create or update route entry to source
                src_entry = &(d->routing_table[rreqmsg->src - 1]);
                
                if (!src_entry->valid) {
                  // No entry exists or invalid
                  src_entry->destSeqNbr = rreqmsg->srcSeqNbr;
                  for (i=0; i<NBR_AODV; i++) {
                    src_entry->prec[i] = 0; // empty precursor list
                  }
                } else {
                  // Update destination sequence number
                  src_entry->destSeqNbr = max(src_entry->destSeqNbr, rreqmsg->srcSeqNbr);
                }
                src_entry->dest = rreqmsg->src;
                src_entry->nextHop = intermed;
                src_entry->hops = rreqmsg->hopCnt + 1;
                src_entry->exptime = now + ACTIVE_ROUTE_TIMEOUT;
                src_entry->valid = 1;
                
                updateExpiryTimer(d->routing_table, d->dataTimer, myID);
                
                // Check if we have a route to destination
                dest_entry = &(d->routing_table[rreqmsg->dest - 1]);
                
                if (rreqmsg->dest==myID || dest_entry->valid) {
                  // We are the destination or we have a route to it
                  if (VERBOSE) {
                    mexPrintf("Node#%d has a route to destination#%d\n", myID, rreqmsg->dest);
                  }
                  
                  if (rreqmsg->dest!=myID) {
                    // I am not the destination, but have a route to it
                    if (VERBOSE) {
                      mexPrintf("Sending first RREP from node with route\n");
                    }
                    
                    dest = dest_entry->dest;
                    seqNbr = dest_entry->destSeqNbr;
                    hopCnt = dest_entry->hops;
                    lifetime = dest_entry->exptime - now;
                    dest_entry->prec[intermed] = 1;
                  } else {
                    // I am the destination itself
                    if (VERBOSE) {
                      mexPrintf("Sending first RREP from destination itself\n");
                    }
                    
                    dest = myID;
                    if (d->seqNbrs[myID - 1] + 1 == rreqmsg->srcSeqNbr) {
                      d->seqNbrs[myID - 1]++;
                    }
                    
                    seqNbr = max(d->seqNbrs[myID - 1], rreqmsg->destSeqNbr);
                    hopCnt = 0;
                    lifetime = ACTIVE_ROUTE_TIMEOUT;
                  }
                  
                  // Create RREP
                  rrepmsg = new RREPMsg;
                  rrepmsg->hopCnt = hopCnt;
                  rrepmsg->dest = dest;
                  rrepmsg->destSeqNbr = seqNbr;
                  rrepmsg->src = rreqmsg->src;
                  rrepmsg->lifetime = lifetime;
                  
                  // Send RREP to previous hop
                  nwkmsg = new GenericNwkMsg;
                  nwkmsg->type = RREP;
                  nwkmsg->intermed = myID;
                  nwkmsg->msg = rrepmsg;
                  ttSendMsg(1, intermed, nwkmsg, 20*8);  // 20 bytes
                  
                  etime = 0.0001;
                } else {
                  // We do not have a route to the destination
                  if (VERBOSE) {
                    mexPrintf("Time: %f Node#%d sending new broadcast\n", now, myID);
                  }
                  
                  // Update RREQ
                  rreqmsg->hopCnt++;
                  rreqmsg->destSeqNbr = max(d->seqNbrs[rreqmsg->dest - 1], rreqmsg->destSeqNbr);
                  
                  // Rebroadcast RREQ
                  nwkmsg = new GenericNwkMsg;
                  nwkmsg->type = RREQ;
                  nwkmsg->intermed = myID;
                  nwkmsg->msg = rreqmsg;
                  ttSendMsg(1, 0, nwkmsg, 24*8);  // 24 bytes
                  
                  etime = 0.0001;
                }
              } else {
                etime = 0.00001; // used if RREQ is dropped
              }
            }
            break;
            
          case RREP:
            rrepmsg = (RREPMsg*) nwkmsg->msg;
            intermed = nwkmsg->intermed;
            
            if (VERBOSE) {
              mexPrintf("Node#%d got an RREP from Node#%d for destination#%d\n", myID, intermed, rrepmsg->dest);
            }
            
            // Initialize or update forward route entry
            dest_entry = &(d->routing_table[rrepmsg->dest - 1]);
            
            if (!dest_entry->valid) {
              // No valid entry exists, initialize new
              if (VERBOSE) {
                mexPrintf("Initializing new forward entry from Node#%d to Node#%d\n", myID, rrepmsg->dest);
              }
              
              dest_entry->dest = rrepmsg->dest;
              dest_entry->nextHop = intermed;
              dest_entry->hops = rrepmsg->hopCnt + 1;
              dest_entry->destSeqNbr = rrepmsg->destSeqNbr;
              dest_entry->exptime = now + rrepmsg->lifetime;
              for (i=0; i<NBR_AODV; i++) {
                dest_entry->prec[i] = 0; // empty precursor list
              }
              dest_entry->valid = 1;
              propagate = 1;
              
              etime2 = 0.0001;;
            } else {
              // Valid forward entry already exists in table
              // Should it be updated?
              cond1 = (rrepmsg->destSeqNbr > dest_entry->destSeqNbr);
              cond2 = ((rrepmsg->destSeqNbr == dest_entry->destSeqNbr) && (rrepmsg->hopCnt+1 < dest_entry->hops));
              
              if (cond1 || cond2) {
                // Update existing entry
                if (VERBOSE) {
                  mexPrintf("Updating existing forward entry from Node#%d to Node#%d\n", myID, rrepmsg->dest);
                }
                
                dest_entry->nextHop = intermed;
                dest_entry->hops = rrepmsg->hopCnt + 1;
                dest_entry->destSeqNbr = rrepmsg->destSeqNbr;
                dest_entry->exptime = now + rrepmsg->lifetime;
                
                propagate = 1;
                etime2 = 0.0001;
              } else {
                // Existing entry should be kept
                // Do not propagate RREP
                if (VERBOSE) {
                  mexPrintf("No entry updated in Node#%d\n", myID);
                }
                
                propagate = 0;
                
                etime2 = 0.0001;;
              }
            }
            
            etime1 = 0;
            
            if (rrepmsg->src == myID) {
              // Original source, no reverse entry exists
              if (VERBOSE) {
                mexPrintf("Node#%d got final RREP for route to Node#%d\n", myID, rrepmsg->dest);
              }
              
              // Inform AODVSend to send buffered data messages
              mailboxmsg = new MailboxMsg;
              mailboxmsg->type = ROUTE_EST;
              mailboxmsg->dest = rrepmsg->dest;
              mailboxmsg->datamsg = NULL;
              ttTryPost("AODVSndBox", mailboxmsg);
              
              etime1 = 0.0001;
              
            } else if (propagate) {
              
              // Update reverse entry from info in RREP
              // and get next hop towards source
              src_entry = &(d->routing_table[rrepmsg->src - 1]);
              src_entry->exptime = now + rrepmsg->lifetime;
              src_entry->prec[intermed-1] = 1; // the node that sent the RREP is a precursor towards the src
              nextHop = src_entry->nextHop;
              
              // Update precursor list for forward entry
              dest_entry->prec[nextHop-1] = 1; // the node that will rcv next RREP is a precursor towards the dest
              
              // Update RREP to continue back propagation
              rrepmsg->hopCnt++;
              
              nwkmsg = new GenericNwkMsg;
              nwkmsg->type = RREP;
              nwkmsg->intermed = myID;
              nwkmsg->msg = rrepmsg;
              
              ttSendMsg(1, nextHop, nwkmsg, 20*8);  // 20 bytes
              
              etime1 = 0.0001;;
              
            }
            updateExpiryTimer(d->routing_table, d->dataTimer, myID);
            
            etime = etime1 + etime2;
            break;
            
          case RERR:
            
            rerrmsg = (RERRMsg*) nwkmsg->msg;
            intermed = nwkmsg->intermed;
            
            if (VERBOSE) {
              mexPrintf("Node#%d got an RERR from Node#%d for destination#%d\n", myID, intermed, rerrmsg->dest);
            }
            
            // Propagate RERR?
            dest_entry = &(d->routing_table[rerrmsg->dest - 1]);
            
            if (dest_entry->valid && dest_entry->nextHop == intermed) {
              // Should send RERR to all nodes in precursor list (neighbors)
              for (i=0; i<NBR_AODV; i++) {
                if (dest_entry->prec[i]) {
                  // Node i+1 uses this node as next hop towards dest, send RERR
                  rerrmsg2 = new RERRMsg;
                  rerrmsg2->dest = dest_entry->dest;
                  rerrmsg2->destSeqNbr = dest_entry->destSeqNbr;
                  rerrmsg2->receiver = i+1;
                  
                  d->RERRlist->appendNode(new DataNode(rerrmsg2, ""));
                }
              }
              
              // Invalidate route
              if (VERBOSE) {
                mexPrintf("Node#%d invalidating route to Node#%d through Node#%d\n", myID, rerrmsg->dest, intermed);
              }
              
              dest_entry->valid = 0;
            }
            
            etime = 0.0001;;
            break;
            
          case HELLO:
            hellomsg = (HelloMsg*) nwkmsg->msg;
            intermed = nwkmsg->intermed;
            //delete nwkmsg;
            
            if (VERBOSE) {
              mexPrintf("Time: %f Node#%d got a hello message from Node#%d\n", now, myID, hellomsg->dest);
            }
            
            // Update time stamp for last HELLO msg
            d->dataHello->nbors[hellomsg->dest - 1] = 1;
            d->dataHello->lastHello[hellomsg->dest - 1] = now;
            
            etime = 0.0001;;
        }
        
      }
      return etime;
      
    case 2:
      // Send next RERR, if any
      dn = (DataNode*) d->RERRlist->getFirst();
      if (dn != NULL) {
        // Retrieve next RERR in list
        rerrmsg = (RERRMsg*) dn->data;
        
        dn->remove();
        delete dn;
        
        // Send RERR to receiver
        nwkmsg = new GenericNwkMsg;
        nwkmsg->type = RERR;
        nwkmsg->intermed = myID;
        nwkmsg->msg = rerrmsg;
        
        if (VERBOSE) {
          mexPrintf("Node#%d sending RERR to Node#%d\n", myID, rerrmsg->receiver);
        }
        
        ttSendMsg(1, rerrmsg->receiver, nwkmsg, 12*8);  // 12 bytes
        ttSleep(0.001);
        return 0.0001;
      } else {
        return FINISHED;
      }
      
    case 3:
      ttSetNextSegment(2);
      return 0.0001;
  }
  
  return FINISHED; // to supress compilation warnings
}
示例#5
0
void *ttGetMsg() {
  return ttGetMsg(1);
}