// Fill a EPMTransferFrameHeaderInfo structure with the corresponding values from an EPM Transfer Frame packet. // The bytes are in ESA/EPM order in the packet, and need to be reversed to be used by Intel/Windows. void ExtractEPMTransferFrameHeaderInfo ( EPMTransferFrameHeaderInfo *header, const EPMTelemetryPacket *epm_packet ) { unsigned char *ptr = ((unsigned char *) epm_packet); header->epmLanSyncMarker = ExtractReversedLong( ptr ); header->spare1 = ExtractChar( ptr ); header->softwareUnitID = ExtractChar( ptr ); header->packetType = ExtractReversedShort( ptr ); header->spare2 = ExtractReversedShort( ptr ); header->numberOfWords = ExtractReversedShort( ptr ); }
void Scanner::AtIdentifier() //判断其余字符 { while(isalnum(c) || c == '_') //字母数字或下划线 { AddToBuffer(c); //加入 ExtractChar(); //读取下一个字符,一直到不满足条件 } IdentifyAndMake(); }
// Extract a Grip housekeeping packet from an EPM packet. // Careful! It is not complete. Not all values are filled. void ExtractGripHealthAndStatusInfo( GripHealthAndStatusInfo *health_packet, const EPMTelemetryPacket *epm_packet ) { const char *ptr; // Point to the actual data in the packet. ptr = epm_packet->sections.rawData; // Skip to the values of interest to us. // DEX-ICD-00383-QS Section 5.2.4.58 says that these items should be at an offset of 68 bytes. // To this must be added an addtional 8 bytes to take into account information about the number // of housekeeping values and the location of the HK Value Check Status List within the packet, // as indicated in EPM-OHB-LI-0039 Table 6-5. ptr += 76; health_packet->horizontalTargetFeedback = ExtractReversedShort( ptr ); health_packet->verticalTargetFeedback = ExtractReversedShort( ptr ); health_packet->toneFeedback = ExtractChar( ptr ); health_packet->cradleDetectors = ExtractChar( ptr ); health_packet->user = ExtractReversedShort( ptr ); health_packet->protocol = ExtractReversedShort( ptr ); health_packet->task = ExtractReversedShort( ptr ); health_packet->step = ExtractReversedShort( ptr ); health_packet->scriptEngineStatusEnum = ExtractReversedShort( ptr ); health_packet->iochannelStatusEnum = ExtractReversedShort( ptr ); health_packet->motionTrackerStatusEnum = ExtractReversedShort( ptr ); health_packet->crewCameraStatusEnum = ExtractReversedShort( ptr ); health_packet->crewCameraRate = ExtractReversedShort( ptr ); health_packet->runningBits = ExtractReversedShort( ptr ); health_packet->cpuUsage = ExtractReversedShort( ptr ); health_packet->memoryUsage = ExtractReversedShort( ptr ); health_packet->freeDiskSpaceC = ExtractReversedLong( ptr ); health_packet->freeDiskSpaceD = ExtractReversedLong( ptr ); health_packet->freeDiskSpaceE = ExtractReversedLong( ptr ); health_packet->crc = ExtractReversedShort( ptr ); }
//注释 void Scanner::AtLineComment() //如果以/开头 { if (c == '/'&&in.peek() == '/') //下一个字符是/ { do { ExtractChar();//提取字符 ,即提取下一个字符 / } while (c != '\n'&&!in.eof());// c=='\n'说明换行了 } }
void Scanner::AtInterger() { while (isdigit(c)) // { AddToBuffer(c); ExtractChar(); } /*if (tolower(c) == 'e' || (c == '.' && in.peek() != '.')) { AddToBuffer(c); ExtractChar(); EatRealFractPart(); }*/ MakeToken(INT_CONST); }
void Scanner::AtOperation() //运算符的判断 { bool match = false; if (!in.eof() && !isalnum(c) && c != '_'&&!isspace(c)) { AddToBuffer(c); if (TryToIdentify()) //判断关系操作符 for example <=此时为真 { match = true; ExtractChar(); } else ReduceBuffer(); } if (!match && !TryToIdentify()) throw "illegal expression"; }
// Extract a real-time science data packet from an EPM packet. void ExtractGripRealtimeDataInfo( GripRealtimeDataInfo *realtime_packet, const EPMTelemetryPacket *epm_packet ) { const char *ptr; int slice; int sensor; int i; short value; long lvalue; EPMTelemetryHeaderInfo telemetry_header; long double timestamp; // Point to the actual data in the packet. ptr = epm_packet->sections.rawData; // Get the acquisition ID and packet count for that acquisition. realtime_packet->acquisitionID = (unsigned long) ExtractReversedLong( ptr ); realtime_packet->rtPacketCount = ExtractReversedLong( ptr ); for ( slice = 0; slice < RT_SLICES_PER_PACKET; slice++ ) { // Get the manipulandum pose data. realtime_packet->dataSlice[slice].poseTick = ExtractReversedLong( ptr ); for ( i = X; i <= Z; i++ ) realtime_packet->dataSlice[slice].position[i] = (double) ExtractReversedShort( ptr ); for ( i = X; i <= M; i++ ) realtime_packet->dataSlice[slice].quaternion[i] = ExtractReversedFloat( ptr ); for ( i = 0; i < 2; i++ ) realtime_packet->dataSlice[slice].markerVisibility[i] = ExtractReversedLong( ptr ); realtime_packet->dataSlice[slice].manipulandumVisibility = ExtractChar( ptr ); // Get the analog data. realtime_packet->dataSlice[slice].analogTick = ExtractReversedLong( ptr ); for ( sensor = 0; sensor < 2; sensor++ ) { for ( i = X; i <=Z; i++ ) { value = ExtractReversedShort( ptr ); realtime_packet->dataSlice[slice].ft[sensor].force[i] = (double) value / 100.0; } for ( i = X; i <=Z; i++ ) { value = ExtractReversedShort( ptr ); realtime_packet->dataSlice[slice].ft[sensor].torque[i] = (double) value / 1000.0; } } for ( i = X; i <= Z; i++ ) { lvalue = ExtractReversedLong( ptr ); realtime_packet->dataSlice[slice].acceleration[i] = ((double) lvalue) / 1000.0 / 9.8; } } // Now timestamp the individual slices as best we can. // First, get the time stamp from the EPM telemetry packet header. ExtractEPMTelemetryHeaderInfo( &telemetry_header, epm_packet ); timestamp = EPMtoSeconds( (&telemetry_header) ); realtime_packet->packetTimestamp = timestamp; // EPM-OHB-SP-0005_iss4 says about EPM Coarse time: // "This double word gives the command execution time (UTC) in elapsed seconds from a defined epoch. // The defined epoch is GPS time, i.e. midnight 5-6 January 1980." // and: // "The time shall be set once all data for a telemetry packet are available by the originator." // Therefore, the last slice is presumed to have been taken just before the time of the packet UTC timestamp. realtime_packet->dataSlice[RT_SLICES_PER_PACKET - 1].bestGuessPoseTimestamp = timestamp; realtime_packet->dataSlice[RT_SLICES_PER_PACKET - 1].bestGuessAnalogTimestamp = timestamp; // Earlier slices are offset from there. for ( slice = RT_SLICES_PER_PACKET - 2; slice >= 0; slice-- ) { #if 0 // Theoretically, we could get a better estimate of the precise time of the slice. // But how the ticks are determined for each slice is not very clear. This code was // intended to use the tick info, but I have commented it out because I cannot figure // out from the documetation that has been provided if this will be better than the // approximate solution that is in the #else below. // If we have a tick for the slice, we use it to compute the offset from the slice // that comes just after it. Otherwise, we assume RT_DEFAULT_SECONDS_PER_SLICE between slices. if ( realtime_packet->dataSlice[slice].poseTick != realtime_packet->dataSlice[slice+1].poseTick ) { realtime_packet->dataSlice[slice].bestGuessPoseTimestamp = realtime_packet->dataSlice[slice+1].bestGuessPoseTimestamp - RT_SECONDS_PER_TICK * ( realtime_packet->dataSlice[slice+1].poseTick - realtime_packet->dataSlice[slice].poseTick ); } else { realtime_packet->dataSlice[slice].bestGuessPoseTimestamp = realtime_packet->dataSlice[slice+1].bestGuessPoseTimestamp - RT_DEFAULT_SECONDS_PER_SLICE; } if ( realtime_packet->dataSlice[slice].analogTick != realtime_packet->dataSlice[slice+1].analogTick ) { realtime_packet->dataSlice[slice].bestGuessAnalogTimestamp = realtime_packet->dataSlice[slice+1].bestGuessAnalogTimestamp - RT_SECONDS_PER_TICK * ( realtime_packet->dataSlice[slice+1].analogTick - realtime_packet->dataSlice[slice].analogTick ); } else { realtime_packet->dataSlice[slice].bestGuessAnalogTimestamp = realtime_packet->dataSlice[slice+1].bestGuessAnalogTimestamp - RT_DEFAULT_SECONDS_PER_SLICE; } #else // Here we assume that slices are spaced equally in time and that the marker and analog // data are aligned such that the last slice occurred at the same time as the packet timestamp. // This is not completely true, but I am not able to do better by reverse engineering the packets // that we have. We don't need millisecond precision anyway for these purposes. realtime_packet->dataSlice[slice].bestGuessPoseTimestamp = realtime_packet->dataSlice[slice+1].bestGuessPoseTimestamp - RT_DEFAULT_SECONDS_PER_SLICE; realtime_packet->dataSlice[slice].bestGuessAnalogTimestamp = realtime_packet->dataSlice[slice+1].bestGuessAnalogTimestamp - RT_DEFAULT_SECONDS_PER_SLICE; #endif } }
// Extract EPM Telemetry Header information into a usable form, taking into account byte order. void ExtractEPMTelemetryHeaderInfo ( EPMTelemetryHeaderInfo *header, const EPMTelemetryPacket *epm_packet ) { // Fill a structure with the header values from an EPM TCP packet. // The bytes are in ESA/EPM order in the TCP packet, and need to be reversed for Windows. unsigned char *ptr = ((unsigned char *) epm_packet); header->transferFrameInfo.epmLanSyncMarker = ExtractReversedLong( ptr ); header->transferFrameInfo.spare1 = ExtractChar( ptr ); header->transferFrameInfo.softwareUnitID = ExtractChar( ptr ); header->transferFrameInfo.packetType = ExtractReversedShort( ptr ); header->transferFrameInfo.spare2 = ExtractReversedShort( ptr ); header->transferFrameInfo.numberOfWords = ExtractReversedShort( ptr ); header->epmSyncMarker = ExtractReversedLong( ptr ); header->subsystemMode = ExtractChar( ptr ); header->subsystemID = ExtractChar( ptr ); header->destination= ExtractChar( ptr ); header->subsystemUnitID = ExtractChar( ptr ); header->TMIdentifier = ExtractReversedShort( ptr ); header->TMCounter = ExtractReversedShort( ptr ); header->model = ExtractChar( ptr ); header->taskID = ExtractChar( ptr ); header->subsystemUnitVersion = ExtractReversedShort( ptr ); header->coarseTime = ExtractReversedLong( ptr ); header->fineTime = ExtractReversedShort( ptr ); header->timerStatus = ExtractChar( ptr ); header->experimentMode = *ptr; ptr++; header->checksumIndicator = ExtractReversedShort( ptr ); header->receiverSubsystemID = ExtractChar( ptr ); header->receiverSubsystemUnitID = ExtractChar( ptr ); header->numberOfWords = ExtractReversedShort( ptr ); }
Token Scanner::GetNextToken() { bool match = false; do { ExtractChar(); //从文件中获取一个字符 //列如 begin,首先c=b;加入缓冲区,重新读取c=e if (state != NONE_ST) match = true; //此时状态为标识符,则调用AtIdentifier switch (state) { case IDENTIFIER_ST: AtIdentifier(); break; case INTEGER_ST: AtInterger(); break; case OPERATION_ST: AtOperation(); break; case EOF_ST: MakeToken(END_OF_FILE); break; case NONE_ST: //不做运算 break; default: break; } if (state == NONE_ST) { AtLineComment(); //注释 if (c == '\n') { ++row; column= 0; } else { first_line= row; //第几列 first_pos = column; //第几行 if (in.eof()) { state = EOF_ST; } else if (!isspace(c)) //空格 { if (isalpha(c) || c == '_') //字母或下划线开头 { state = IDENTIFIER_ST; //表明其实标识符 } else if (isdigit(c)) { state = INTEGER_ST; } else { state = OPERATION_ST; } AddToBuffer(c); } } } } while (!match); return token; }