예제 #1
0
SSIZE_T parse( BYTE *data, SIZE_T len, Descriptors &descriptors ) {
	SSIZE_T offset = 0;

	WORD compatibilityLen = RW(data,offset);
	if (!compatibilityLen) {
		//	Ignore if not present
		return 2;
	}
	WORD descriptorCount  = RW(data,offset);

	printf( "[dsmcc::compatiblity] Compatibility descriptor: dataLen=%ld, descLen=%d, count=%d\n",
	 	len, compatibilityLen, descriptorCount );

	//	Check if len is ok
	if (len < compatibilityLen) {
		printf( "[dsmcc::compatiblity] No data available to parse Compatibility descriptor: descLen=%ld, available=%d\n",
			len, compatibilityLen );
		return compatibilityLen+2;
	}

	//	Parse descriptors
	for (WORD desc=0; desc<descriptorCount; desc++) {
		Descriptor desc;

		desc.type      = RB(data,offset);
		
		//BYTE dLen      = RB(data,offset);
		offset += 1;
		
		desc.specifier = RDW(data,offset);
		desc.model     = RW(data,offset);
		desc.version   = RW(data,offset);

		//	Parse sub descriptors
		BYTE subCount = RB(data,offset);		
		for (BYTE sub=0; sub<subCount; sub++) {
			BYTE subType = RB(data,offset);
			BYTE subLen  = RB(data,offset);
			//	AdditionalInformation
			offset += subLen;
			printf( "[dsmcc::compatibility] Warning, subdescriptor not parsed: count=%d, type=%x, len=%x\n", subCount, subType, subLen );
		}

		descriptors.push_back( desc );
	}
	
	return compatibilityLen+2; 
}
예제 #2
0
SSIZE_T Object::objectKey( const BYTE *data, SIZE_T len, ObjectKeyType &key ) {
    SSIZE_T off=0;

    //  Object key len
    BYTE objectKeyLen = RB(data,off);
    if (objectKeyLen > 4) {
        throw std::bad_cast();
    }
    assert(len >= SIZE_T(1+objectKeyLen));
	
    //  Object key
	key = RDW( data, off );

	//printf( "[dsmcc::Object] Parsing object key: len=%08lx, key=%08lx\n", len, key );

    return off;
}
예제 #3
0
SSIZE_T parse( BYTE *data, SIZE_T /*len*/, Modules &modules, bool skipVersion/*=false*/ ) {
	SSIZE_T offset = 0;
	
	WORD numberOfModules = RW(data,offset);
    for (int mod=0; mod<numberOfModules; mod++) {
		Type module;

        module.id      = RW(data,offset);
        module.size    = RDW(data,offset);
		module.version = (skipVersion) ? 0 : RB(data,offset);
        BYTE moduleInfoLen = RB(data,offset);
        if (moduleInfoLen) {
            module.info.copy( (char *)(data+offset), moduleInfoLen );
            offset += moduleInfoLen;
        }

		modules.push_back( module );
    }

	return offset;
}
예제 #4
0
Object *Object::parseObject( ResourceManager *resMgr, Module *module, SSIZE_T &off ) {
    Object *obj;
	ObjectLocation loc;
    BYTE buf[BIOP_MAX_HEADER];

    SSIZE_T offset = 0;
    SIZE_T len = module->read( off, buf, BIOP_MAX_HEADER );
    if (len < BIOP_MAX_HEADER) {
        printf( "[dsmcc::Object] Warning: Not enough buffer: len=%ld, offset=%ld\n", len, offset );
        return NULL;
    }

    DWORD magic = RDW(buf,offset);
    if (magic != BIOP_MAGIC) {
        printf( "[dsmcc::Object] Warning: Bad magic number: magic=%x, found=%lx\n", BIOP_MAGIC, magic );
        return NULL;
    }

    WORD biopVersion = RW(buf,offset);
    if (biopVersion != BIOP_VER) {
        printf( "[dsmcc::Object] Warning: Invalid version\n" );
        return NULL;
    }

    BYTE byteOrder = RB(buf,offset);
    if (byteOrder) {
        printf( "[dsmcc::Object] Warning: Invalid byte order\n" );
        return NULL;
    }

    BYTE msgType = RB(buf,offset);
    if (msgType) {
        printf( "[dsmcc::Object] Warning: Invalid type\n" );
        return NULL;
    }

    //  Check BIOP message size
    DWORD msgSize = RDW(buf,offset);
    if (module->size()-off-offset < msgSize) {
        printf( "[dsmcc::Object] Warning: Not enough bytes for BIOP message: msgSize=%ld, rest%ld\n", msgSize, module->size()-off-offset );
        return NULL;
    }
    //  12 bytes parsed = BIOP_MIN_HEADER

    offset += objectKey( buf+offset, len-offset, loc.keyID );

    DWORD objectKindLen = RDW(buf,offset);
    if (objectKindLen != 4) {
        printf( "[dsmcc::Object] Warning: Invalid object kind\n" );
        return NULL;
    }

	//	Chapter 11: The downloadID field of the DownloadDataBlock messages shall have the same value
	//	as the carouselID field of the U-U Object Carousel
	loc.carouselID = module->downloadID();
	loc.moduleID   = module->id();

    DWORD objectKind = RDW(buf,offset);
    switch (objectKind) {
        case BIOP_OBJECT_FILE:
            obj = new File( loc );
            break;
        case BIOP_OBJECT_DIR:
        case BIOP_OBJECT_GW:
            obj = new Directory( loc );
            break;
		// case BIOP_OBJECT_STR:
		// 	break;
		case BIOP_OBJECT_STE:
			obj = new StreamEvent( loc );
			break;
        default:
            obj = NULL;
            printf( "[dsmcc::Object] Warning: BIOP object kind %lx not processed\n", objectKind );
    }

	WORD objectInfoLen = RW(buf,offset);
	
    //  Update offset (27 bytes parsed = BIOP_MAX_HEADER)
    off += offset;
    if (obj && !obj->parse( resMgr, module, off, objectInfoLen )) {
		delete obj;
		obj = NULL;
	}
	
    return obj;
}
예제 #5
0
void parseDescriptors( const util::Buffer &info, desc::MapOfDescriptors &descriptors ) {
	SIZE_T len = info.length();
	BYTE *data = (BYTE *)info.buffer();
	SSIZE_T offset = 0;

	while (offset < len) {
		BYTE dTag = RB(data,offset);
		BYTE dLen = RB(data,offset);
		SSIZE_T parsed = offset;

		printf( "[dsmcc::module] Parse tag descriptor: tag=%x, len=%d\n", dTag, dLen );

		switch (dTag) {
			case MODULE_DESC_TYPE:	//	Type descriptor
			{
				std::string type( (char *)(data+parsed), dLen );
				descriptors[dTag] = type;
				parsed += dLen;
				break;
			}
			case MODULE_DESC_NAME:	//	Name descriptor
			{
				std::string name( (char *)(data+parsed), dLen );
				descriptors[dTag] = name;
				parsed += dLen;
				break;
			}
			case MODULE_DESC_INFO:	//	Info descriptor
			{
				module::InfoDescriptor desc;
				desc.language = std::string( (char *)(data+parsed), 3 );
				desc.text     = std::string( (char *)(data+parsed+3), dLen-3 );
				descriptors[dTag] = desc;
				parsed += dLen;
				break;
			}
			case MODULE_DESC_LINK:	//	Module link descriptor
			{
				module::LinkDescriptor desc;
				desc.position = RB(data,parsed);
				desc.moduleID = RW(data,parsed);
				descriptors[dTag] = desc;
				break;
			}
			case MODULE_DESC_CRC32:	//	CRC32 descriptor
			{
				DWORD crc = RDW(data,parsed);
				descriptors[dTag] = crc;				
				break;
			}
			case MODULE_DESC_LOCATION:	//	Location descriptor
			{
				BYTE location = RB(data,parsed);
				descriptors[dTag] = location;				
				break;
			}
			case MODULE_DESC_EST_DOWNLOAD:	//	Estimated download time descriptor
			{
				DWORD est = RDW(data,parsed);
				descriptors[dTag] = est;				
				break;
			}
			case MODULE_DESC_COMPRESSION:	//	Compression type descriptor
			case MODULE_DESC_COMPRESSED:
			{
				module::CompressionTypeDescriptor desc;
				desc.type = RB(data,parsed);
				desc.originalSize = RDW(data,parsed);
				descriptors[dTag] = desc;								
				break;
			}
		};

		offset += dLen;
		if (offset != parsed) {
			printf( "[dsmcc::module] Descriptor not parsed or parsed was incomplete: dTag=%x, len=%d, parsed=%ld\n",
				dTag, dLen, parsed );
		}		
	}

	//printf( "[dsmcc::module] Descriptors parsed: %d\n", descriptors.size() );
}
  // Initialization process
void EkfNode::init() {
  /**************************************************************************
   * Initialize firstRun, time, and frame names
   **************************************************************************/
  // Set first run to true for encoders. Once a message is received, this will
  // be set to false.
  firstRunEnc_ = true;
  firstRunSys_ = true;
  // Set Times
  ros::Time currTime = ros::Time::now();
  lastEncTime_ = currTime;
  lastSysTime_ = currTime;
  // Use the ROS parameter server to initilize parameters
  if(!private_nh_.getParam("base_frame", base_frame_))
    base_frame_ = "base_link";
  if(!private_nh_.getParam("odom_frame", base_frame_))
    odom_frame_ = "odom";
  if(!private_nh_.getParam("map_frame", map_frame_))
    map_frame_ = "map";

  /**************************************************************************
   * Initialize state for ekf_odom_ and ekf_map_
   **************************************************************************/
  // Create temp array to initialize state
  double state_temp[] = {0, 0, 0, 0, 0, 0};
  // And a std::vector, which will be used to initialize an Eigen Matrix
  std::vector<double> state (state_temp, state_temp + sizeof(state_temp) / sizeof(double));
  // Check the parameter server and initialize state
  if(!private_nh_.getParam("state", state)) {
    ROS_WARN_STREAM("No state found. Using default.");
  }
  // Check to see if the size is not equal to 6
  if (state.size() != 6) {
    ROS_WARN_STREAM("state isn't 6 elements long!");
  }
  // And initialize the Matrix
  typedef Matrix<double, 6, 1> Vector6d;
  Vector6d stateMat(state.data());
  std::cout << "state_map = " << std::endl;
  std::cout << stateMat << std::endl;
  ekf_map_.initState(stateMat);

  // Odom is always initialized at all zeros.
  stateMat << 0, 0, 0, 0, 0, 0;
  ekf_odom_.initState(stateMat);
  std::cout << "state_odom = " << std::endl;
  std::cout << stateMat << std::endl;

  /**************************************************************************
   * Initialize covariance for ekf_odom_ and ekf_map_
   **************************************************************************/
  // Create temp array to initialize covariance
  double cov_temp[] = {0.01, 0, 0, 0, 0, 0,
		       0, 0.01, 0, 0, 0, 0,
		       0, 0, 0.01, 0, 0, 0,
		       0, 0, 0, 0.01, 0, 0,
		       0, 0, 0, 0, 0.01, 0,
		       0, 0, 0, 0, 0, 0.01};
  // And a std::vector, which will be used to initialize an Eigen Matrix
  std::vector<double> cov (cov_temp, cov_temp + sizeof(cov_temp) / sizeof(double));
  // Check the parameter server and initialize cov
  if(!private_nh_.getParam("covariance", cov)) {
    ROS_WARN_STREAM("No covariance found. Using default.");
  }
  // Check to see if the size is not equal to 36
  if (cov.size() != 36) {
    ROS_WARN_STREAM("cov isn't 36 elements long!");
  }
  // And initialize the Matrix
  typedef Matrix<double, 6, 6, RowMajor> Matrix66;
  Matrix66 covMat(cov.data());
  std::cout << "covariance = " << std::endl;
  std::cout << covMat << std::endl;
  ekf_map_.initCov(covMat);

  // Initialize odom covariance the same as the map covariance (this isn't
  // correct. But, since it is all an estimate anyway, it should be fine.
  ekf_odom_.initCov(covMat);

  /**************************************************************************
   * Initialize Q for ekf_odom_ and ekf_map_
   **************************************************************************/
  // Create temp array to initialize Q
  double Q_temp[] = {0.01, 0, 0, 0, 0, 0,
		     0, 0.01, 0, 0, 0, 0,
		     0, 0, 0.01, 0, 0, 0,
		     0, 0, 0, 0.01, 0, 0,
		     0, 0, 0, 0, 0.01, 0,
		     0, 0, 0, 0, 0, 0.01};
  // And a std::vector, which will be used to initialize an Eigen Matrix
  std::vector<double> Q (Q_temp, Q_temp + sizeof(Q_temp) / sizeof(double));
  // Check the parameter server and initialize Q
  if(!private_nh_.getParam("Q", Q)) {
    ROS_WARN_STREAM("No Q found. Using default.");
  }
  // Check to see if the size is not equal to 36
  if (Q.size() != 36) {
    ROS_WARN_STREAM("Q isn't 36 elements long!");
  }
  // And initialize the Matrix
  Matrix66 QMat(Q.data());
  std::cout << "Q = " << std::endl;
  std::cout << QMat << std::endl;
  ekf_map_.initSystem(QMat);
  ekf_odom_.initSystem(QMat);

  /**************************************************************************
   * Initialize Decawave for ekf_map_ (not used in ekf_odom_)
   **************************************************************************/
  // Create temp array to initialize R for DecaWave
  double RDW_temp[] = {0.01, 0, 0, 0,
		       0, 0.01, 0, 0,
		       0, 0, 0.01, 0,
		       0, 0, 0, 0.01};
  // And a std::vector, which will be used to initialize an Eigen Matrix
  std::vector<double> RDW (RDW_temp, RDW_temp + sizeof(RDW_temp) / sizeof(double));
  // Check the parameter server and initialize RDW
  if(!private_nh_.getParam("DW_R", RDW)) {
    ROS_WARN_STREAM("No DW_R found. Using default.");
  }
  // Check to see if the size is not equal to 16
  if (RDW.size() != 16) {
    ROS_WARN_STREAM("DW_R isn't 16 elements long!");
  }
  // And initialize the Matrix
  typedef Matrix<double, 4, 4, RowMajor> Matrix44;
  Matrix44 RDWMat(RDW.data());
  std::cout << "RDecaWave = " << std::endl;
  std::cout << RDWMat << std::endl;

  // Create temp array to initialize beacon locations for DecaWave
  double DWBL_temp[] = {0, 0,
		       5, 0,
		       5, 15,
		       0, 15};
  // And a std::vector, which will be used to initialize an Eigen Matrix
  std::vector<double> DWBL (DWBL_temp, DWBL_temp + sizeof(DWBL_temp) / sizeof(double));
  // Check the parameter server and initialize DWBL
  if(!private_nh_.getParam("DW_Beacon_Loc", DWBL)) {
    ROS_WARN_STREAM("No DW_Beacon_Loc found. Using default.");
  }
  // Check to see if the size is not equal to 8
  if (DWBL.size() != 8) {
    ROS_WARN_STREAM("DW_Beacon_Loc isn't 8 elements long!");
  }
  // And initialize the Matrix
  typedef Matrix<double, 4, 2, RowMajor> Matrix42;
  Matrix42 DWBLMat(DWBL.data());
  std::cout << "DW_Beacon_Loc = " << std::endl;
  std::cout << DWBLMat << std::endl;

  MatrixXd DecaWaveBeaconLoc(4,2);
  MatrixXd DecaWaveOffset(2,1);
  double DW_offset_x;
  double DW_offset_y;
  if(!private_nh_.getParam("DW_offset_x", DW_offset_x))
    DW_offset_x = 0.0;
  if(!private_nh_.getParam("DW_offset_y", DW_offset_y))
    DW_offset_y = 0.0;
  DecaWaveOffset << DW_offset_x, DW_offset_y;
  std::cout << "DecaWaveOffset = " << std::endl;
  std::cout << DecaWaveOffset << std::endl;

  ekf_map_.initDecaWave(RDWMat, DWBLMat, DecaWaveOffset);
  // Decawave is not used in odom, so no need to initialize

  /**************************************************************************
   * Initialize Encoders for ekf_odom_ and ekf_map_
   **************************************************************************/
  // Create temp array to initialize R for DecaWave
  double REnc_temp[] = {0.01, 0,
			0, 0.01};
  // And a std::vector, which will be used to initialize an Eigen Matrix
  std::vector<double> REnc (REnc_temp, REnc_temp + sizeof(REnc_temp) / sizeof(double));
  // Check the parameter server and initialize RDW
  if(!private_nh_.getParam("Enc_R", REnc)) {
    ROS_WARN_STREAM("No Enc_R found. Using default.");
  }
  // Check to see if the size is not equal to 4
  if (REnc.size() != 4) {
    ROS_WARN_STREAM("Enc_R isn't 4 elements long!");
  }
  // And initialize the Matrix
  typedef Matrix<double, 2, 2, RowMajor> Matrix22;
  Matrix22 REncMat(REnc.data());
  std::cout << "R_Enc = " << std::endl;
  std::cout << REncMat << std::endl;

  double b, tpmRight, tpmLeft;
  if(!private_nh_.getParam("track_width", b))
    b = 1;
  if(!private_nh_.getParam("tpm_right", tpmRight))
    tpmRight = 1;
  if(!private_nh_.getParam("tpm_left", tpmLeft))
    tpmLeft = 1;
  ekf_map_.initEnc(REncMat, b, tpmRight, tpmLeft);
  ekf_odom_.initEnc(REncMat, b, tpmRight, tpmLeft);
  std::cout << "track_width = " << b << std::endl;
  std::cout << "tpm_right   = " << tpmRight << std::endl;
  std::cout << "tpm_left    = " << tpmLeft << std::endl;

  /**************************************************************************
   * Initialize IMU for ekf_odom_ and ekf_map_
   **************************************************************************/
  double RIMU;
  if(!private_nh_.getParam("R_IMU", RIMU))
    RIMU = 0.01;
  ekf_map_.initIMU(RIMU);
  ekf_odom_.initIMU(RIMU);
  std::cout << "R_IMU = " << RIMU << std::endl;

  // Publish the initialized state and exit initialization.
  publishState(currTime);
  ROS_INFO_STREAM("Finished with initialization.");
}