68 #include "rnr/rnrconfig.h" 111 LaeVL6180SensorInfo::LaeVL6180SensorInfo()
119 LaeVL6180SensorInfo::LaeVL6180SensorInfo(
int nIndex,
123 const std::string &strDesc)
127 m_fBeamDir = fBeamDir;
128 m_fDeadzone = fDeadzone;
141 LaeVL6180SensorInfo::~LaeVL6180SensorInfo()
157 void LaeVL6180SensorInfo::getProps(
int &nIndex,
159 std::string &strRadiationType,
165 std::string &strDesc)
169 strRadiationType =
"infrared";
171 fBeamDir = m_fBeamDir;
172 fDeadzone = m_fDeadzone;
183 LaeVL6180Mux::LaeVL6180Mux(
LaeI2CMux &mux,
187 const string &strNameId,
188 const string &strDesc) :
189 m_mux(mux), m_nChan(nChan), m_fBeamDir(fBeamDir), m_fDeadzone(fDeadzone),
190 m_strNameId(strNameId), m_strDesc(strDesc)
193 m_bBlackListed =
false;
196 m_uAlsIntPeriod = 50;
198 m_regRangeOffset = (byte_t)0;
199 m_regRangeCrossTalk = (u16_t)0;
200 m_regAlsGain = (byte_t)gainAnalogToEnum(m_fAlsGain);
201 m_regAlsIntPeriod = (u16_t)(m_uAlsIntPeriod - 1);
204 m_fAmbientLight = 0.0;
206 pthread_mutex_init(&m_mutex, NULL);
210 m_mux(src.m_mux), m_nChan(src.m_nChan),
211 m_fBeamDir(src.m_fBeamDir), m_fDeadzone(src.m_fDeadzone),
212 m_strNameId(src.m_strNameId)
225 pthread_mutex_destroy(&
m_mutex);
243 rc =
readReg8(VL6180X_SYSTEM_FRESH_OUT_OF_RESET, reset);
245 if( (rc == LAE_OK) && (reset == 0) )
247 LOGDIAG3(
"VL6180 sensor %s(%d): " 248 "Not fresh out of reset: No initialization required.",
266 LOGDIAG3(
"VL6180 sensor %s(%d): Initialized.",
273 LOGERROR(
"VL6180 sensor %s(%d): Black listed: Failed to initialize.",
323 rc =
writeReg8(VL6180X_SYSTEM_FRESH_OUT_OF_RESET, 0);
336 writeReg8(VL6180X_SYSTEM_INTERRUPT_CONFIG_GPIO, (4 << 3)|(4));
339 writeReg8(VL6180X_SYSTEM_MODE_GPIO1, 0x10);
343 writeReg8(VL6180X_READOUT_AVERAGING_SAMPLE_PERIOD, 48);
349 writeReg8(VL6180X_SYSRANGE_VHV_REPEAT_RATE, 0xFF);
352 writeReg8(VL6180X_SYSRANGE_VHV_RECALIBRATE, 0x01);
362 writeReg8(VL6180X_SYSRANGE_INTERMEASUREMENT_PERIOD, 0x09);
366 writeReg8(VL6180X_SYSALS_INTERMEASUREMENT_PERIOD, 0x0A);
370 writeReg8(VL6180X_SYSRANGE_MAX_CONVERGENCE_TIME, 0x32);
371 writeReg8(VL6180X_SYSRANGE_RANGE_CHECK_ENABLES, 0x10 | 0x01);
372 writeReg16(VL6180X_SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, 0x7B );
374 writeReg8(VL6180X_SYSRANGE_RANGE_IGNORE_VALID_HEIGHT, 255);
376 writeReg8(VL6180X_FIRMWARE_RESULT_SCALER, 0x01);
380 double fAlsGain, uint_t uAlsIntPeriod)
382 byte_t regRangeOffset;
383 u16_t regRangeCrossTalk;
385 u16_t regAlsIntPeriod;
397 regRangeOffset = (byte_t)
cap((
int)uRangeOffset,
408 regRangeCrossTalk = (u16_t)
cap(uRangeCrossTalk,
420 regAlsIntPeriod = (u16_t)(uAlsIntPeriod - 1);
427 rc =
writeReg8(VL6180X_SYSRANGE_PART_TO_PART_RANGE_OFFSET, regRangeOffset);
434 LOGDIAG3(
"Failed to write new range part-to-part " 435 "offset register value %u.", regRangeOffset);
444 rc =
writeReg16(VL6180X_SYSRANGE_CROSSTALK_COMPENSATION_RATE,
452 LOGDIAG3(
"Failed to write new range cross-talk compensation " 453 "register value %u.", regRangeCrossTalk);
462 rc =
writeReg8(VL6180X_SYSALS_ANALOGUE_GAIN, (byte_t)(0x40|regAlsGain));
470 LOGDIAG3(
"Failed to write new ALS gain register value %u.", regAlsGain);
479 rc =
writeReg16(VL6180X_SYSALS_INTEGRATION_PERIOD, regAlsIntPeriod);
487 LOGDIAG3(
"Failed to write new ALS integration period register value %u.",
517 u16_t ®RangeCrossTalk,
519 u16_t ®AlsIntPeriod)
533 readReg8(VL6180X_IDENTIFICATION_MODEL_ID,
id.idModel);
534 readReg8(VL6180X_IDENTIFICATION_MODEL_REV_MAJOR,
id.idModelRevMajor);
535 readReg8(VL6180X_IDENTIFICATION_MODEL_REV_MINOR,
id.idModelRevMinor);
536 readReg8(VL6180X_IDENTIFICATION_MODULE_REV_MAJOR,
id.idModuleRevMajor);
537 readReg8(VL6180X_IDENTIFICATION_MODULE_REV_MINOR,
id.idModuleRevMinor);
539 readReg16(VL6180X_IDENTIFICATION_DATE,
id.idDate);
540 readReg16(VL6180X_IDENTIFICATION_TIME,
id.idTime);
549 static byte_t startMeas = 0x01;
550 static byte_t measDone = 0x04;
551 static byte_t statusErrMask = 0xf0;
552 static byte_t statusErrOverflowRaw = 0xd0;
553 static byte_t statusErrOverflow = 0xf0;
554 static byte_t clearInterrupts = 0x07;
580 if( msec > msecWait )
582 LOGDIAG3(
"VL6180 sensor %s(%d): Range sensor busy.",
584 rc = -LAE_ECODE_TIMEDOUT;
592 rc =
writeReg8(VL6180X_SYSRANGE_START, startMeas);
607 if( msec > msecWait )
609 LOGDIAG3(
"VL6180 sensor %s(%d): Range measurement timed out.",
611 rc = -LAE_ECODE_TIMEDOUT;
615 writeReg8(VL6180X_SYSTEM_INTERRUPT_CLEAR, clearInterrupts);
622 if( (rc =
readReg8(VL6180X_RESULT_RANGE_VAL, valRange)) == LAE_OK )
654 fRange = (double)valRange / 1000.0;
673 else if( rc == -LAE_ECODE_TIMEDOUT )
698 static byte_t startMeas = 0x01;
699 static byte_t measDone = 0x20;
700 static byte_t statusErrMask = 0xf0;
701 static double alsRes = 0.32;
727 if( msec > msecWait )
729 LOGDIAG3(
"VL6180 sensor %s(%d): Ambient light sensor busy.",
731 rc = -LAE_ECODE_TIMEDOUT;
739 rc =
writeReg8(VL6180X_SYSALS_START, startMeas);
749 if( msec > msecWait )
751 LOGDIAG3(
"VL6180 sensor %s(%d): Ambient light measurement timed out.",
753 rc = -LAE_ECODE_TIMEDOUT;
762 if( (rc =
readReg16(VL6180X_RESULT_ALS_VAL, valAlsRaw)) == LAE_OK )
764 rc =
readReg8(VL6180X_RESULT_ALS_STATUS, valStatus);
774 valStatus &= statusErrMask;
779 rc = -LAE_ECODE_BAD_VAL;
786 alsLux = alsRes * ((double)valAlsRaw /
m_fAlsGain) *
818 static byte_t statusReady = 0x01;
826 for(msec = 0; msec <= msecWait; ++msec)
829 if( (
readReg8(regStatus, val) == LAE_OK) && (val & statusReady) )
846 static byte_t clearInterrupts = 0x07;
854 for(msec = 0; msec <= msecWait; ++msec)
856 if(
readReg8(VL6180X_RESULT_INTERRUPT_STATUS_GPIO, val) == LAE_OK )
883 u16_t regOffset = VL6180X_SYSRANGE_PART_TO_PART_RANGE_OFFSET;
884 double fWhiteTgt = 0.050;
899 if( (rc =
readReg8(regOffset, (byte_t &)offset)) == LAE_OK )
905 LOGDIAG3(
"Failed to read SYSRANGE_PART_TO_PART_RANGE_OFFSET (0x%04x) " 906 "register. Cannot proceed with calibration.",
914 for(i = 0, fSum = 0.0, nMeasured = 0; i<maxIters; ++i)
927 if( nMeasured < minGood )
929 LOGDIAG3(
"Made %d/%d range meassurements. A minimum of %d are required." 930 "Cannot proceed with calibration.",
932 return -LAE_ECODE_IO;
935 nOffsetPre = (int)offset;
936 fAvgPre = fSum / (double)nMeasured;
941 if( (fAvgPre >= fWhiteTgt-fRes) && (fAvgPre <= fWhiteTgt+fRes) )
943 nOffsetPost = nOffsetPre;
951 if( (rc =
writeReg8(regOffset, 0)) == LAE_OK )
957 LOGDIAG3(
"Failed to write SYSRANGE_PART_TO_PART_RANGE_OFFSET (0x%04x) " 958 "register. Cannot proceed with calibration.",
966 for(i = 0, fSum = 0.0, nMeasured = 0; i<maxIters; ++i)
979 if( nMeasured < minGood )
981 LOGDIAG3(
"Made %d/%d range meassurements. A minimum of %d are required." 982 "Cannot proceed with calibration.",
984 return -LAE_ECODE_IO;
987 fAvgPost = fSum / (double)nMeasured;
988 nOffsetPost = (int)((fWhiteTgt - fAvgPost) * 1000.0);
990 offset = (s8_t)(nOffsetPost);
995 if( (rc =
writeReg8(regOffset, (byte_t)offset)) == LAE_OK )
1001 LOGDIAG3(
"Failed to write new SYSRANGE_PART_TO_PART_RANGE_OFFSET (0x%04x) " 1002 "register. Calibration failed.",
1010 for(i = 0, fSum = 0.0, nMeasured = 0; i<maxIters; ++i)
1023 if( nMeasured < minGood )
1025 LOGWARN(
"Made %d/%d range meassurements. A minimum of %d are required." 1026 "Post performance evaluation is unknown.",
1027 nMeasured, minGood);
1031 fAvgPost = fSum / (double)nMeasured;
1039 u16_t regComp = VL6180X_SYSRANGE_CROSSTALK_COMPENSATION_RATE;
1040 u16_t regRate = VL6180X_RESULT_RANGE_RETURN_RATE;
1041 double fBlackTgt = 0.100;
1059 if( (rc =
writeReg16(regComp, 0)) == LAE_OK )
1065 LOGDIAG3(
"Failed to write SYSRANGE_CROSSTALK_COMPENSATION_RATE (0x%04x) " 1066 "register. Cannot proceed with calibration.",
1074 for(i = 0, fSumRange = 0.0, fSumRate = 0.0, nMeasured = 0; i<maxIters; ++i)
1081 fSumRange += fRange;
1082 fSumRate += (double)val;
1090 if( nMeasured < minGood )
1092 LOGDIAG3(
"Made %d/%d rate/range meassurements. " 1093 "A minimum of %d are required." 1094 "Cannot proceed with calibration.",
1095 nMeasured, minGood);
1096 return -LAE_ECODE_IO;
1099 fAvgRange = fSumRange / (double)nMeasured;
1100 fAvgRate = fSumRate / (double)nMeasured;
1102 val = (byte_t)(fAvgRate * (1.0 - fAvgRange/fBlackTgt));
1107 if( (rc =
writeReg16(regComp, val)) == LAE_OK )
1113 LOGDIAG3(
"Failed to write new SYSRANGE_CROSSTALK_COMPENSATION_RATE (0x%04x)" 1114 " register value. Calibration failed.",
1120 nCrossTalk = (int)val & 0x0ff;
1127 if( (eAlsGain >= 0) && (eAlsGain <
GAIN_NumOf) )
1141 double diff, minDiff;
1143 fAlsGain = fabs(fAlsGain);
1163 if( diff < minDiff )
1179 req[n++] = (byte_t)((reg >> 8) & 0xff);
1180 req[n++] = (byte_t)(reg & 0xff);
1186 LOGDIAG3(
"VL6180 sensor %s(%d): Failed to read register 0x%04x.",
1200 req[n++] = (byte_t)((reg >> 8) & 0xff);
1201 req[n++] = (byte_t)(reg & 0xff);
1207 val = ((u16_t)(rsp[0]) << 8) | (u16_t)rsp[1];
1211 LOGDIAG3(
"VL6180 sensor %s(%d): Failed to read register 0x%04x.",
1225 req[n++] = (byte_t)((reg >> 8) & 0xff);
1226 req[n++] = (byte_t)(reg & 0xff);
1235 LOGDIAG3(
"VL6180 sensor %s(%d): Failed to write register 0x%04x.",
1250 req[n++] = (byte_t)((reg >> 8) & 0xff);
1251 req[n++] = (byte_t)(reg & 0xff);
1252 req[n++] = (byte_t)((val >> 8) & 0xff);
1253 req[n++] = (byte_t)(val & 0xff);
1261 LOGDIAG3(
"VL6180 sensor %s(%d): Failed to write register 0x%04x.",
1283 for(
size_t i = 0; i <
m_vecToF.size(); ++i)
1304 for(
size_t i = 0; i <
m_vecToF.size(); ++i)
1313 LaeDesc::MapDescRangeSensor::const_iterator iter;
1325 iter->second->m_nChan,
1326 iter->second->m_fDir,
1327 iter->second->m_fDeadzone,
1329 iter->second->m_strDesc));
1336 for(
size_t i = 0; i <
m_vecToF.size(); ++i)
1338 if( (rc =
m_vecToF[i]->readId(ident)) < 0 )
1340 LOGWARN(
"VL6180 %s sensor: Failed to read identity.",
1344 if( (rc =
m_vecToF[i]->initSensor(
true)) < 0 )
1346 LOGWARN(
"VL6180 %s sensor: Failed to initialize sensor.",
1352 LOGDIAG3(
"VL6180 %s sensor connected:\n" 1354 " Model: %u v%u.%u\n" 1359 ident.idModel, ident.idModelRevMajor, ident.idModelRevMinor,
1360 ident.idModuleRevMajor, ident.idModuleRevMinor,
1361 ident.idDate, ident.idTime);
1373 int nRangeCrossTalk;
1378 for(
size_t i = 0; i <
m_vecToF.size(); ++i)
1383 fAlsGain, nAlsIntPeriod);
1385 rc =
m_vecToF[i]->tune((uint_t)nRangeOffset, (uint_t)nRangeCrossTalk,
1386 fAlsGain, (uint_t)nAlsIntPeriod);
1390 LOGDIAG3(
"VL6180 range sensor %s tuned.", strKey.c_str());
1394 LOGERROR(
"VL6180 range sensor %s: Failed to tune sensor.",
1400 LOGDIAG2(
"Tuned VL6180 range sensor group.");
1407 LOGDIAG2(
"Reloading VL6180 range sensor group tuning parameters...");
1419 if( (nNumSensors = (
int)
m_vecToF.size()) == 0 )
1427 for(
int sensorIndex = 0; sensorIndex < nNumSensors; ++sensorIndex)
1429 fRange =
m_vecToF[sensorIndex]->measureRange(fAmbient);
1430 RtDb.m_range[sensorIndex].m_fRange = fRange;
1438 RtDb.m_range[
m_nAlsIndex].m_fAmbientLight = fAmbient;
1450 if( (i = keyIndex(strKey)) >= 0 )
1452 m_vecToF[i]->getMeasurements(fRange, fAmbient);
1457 LOGERROR(
"VL6180 range sensor %s does not exist.", strKey.c_str());
1458 return -LAE_ECODE_BAD_VAL;
1463 std::vector<double> &vecRanges)
1471 for(
size_t i = 0; i <
m_vecToF.size(); ++i)
1473 m_vecToF[i]->getMeasurements(fRange, fAmbient);
1475 vecNames.push_back(
m_vecToF[i]->getNameId());
1476 vecRanges.push_back(fRange);
1487 if( (i = keyIndex(strKey)) >= 0 )
1489 m_vecToF[i]->getMeasurements(fRange, fLux);
1494 LOGERROR(
"VL6180 range sensor %s does not exist.", strKey.c_str());
1495 return -LAE_ECODE_BAD_VAL;
1500 std::vector<double> &vecLux)
1508 for(
size_t i = 0; i <
m_vecToF.size(); ++i)
1510 m_vecToF[i]->getMeasurements(fRange, fAmbient);
1512 vecNames.push_back(
m_vecToF[i]->getNameId());
1513 vecLux.push_back(fAmbient);
1520 std::string &strRadiationType,
1528 if( (i = keyIndex(strKey)) >= 0 )
1530 strRadiationType =
m_vecToF[i]->getRadiationType();
1532 fBeamDir =
m_vecToF[i]->getBeamDir();
1533 m_vecToF[i]->getMinMax(fMin, fMax);
1538 LOGERROR(
"VL6180 range sensor %s does not exist.", strKey.c_str());
1539 return -LAE_ECODE_BAD_VAL;
1548 if( (i = keyIndex(strKey)) >= 0 )
1554 LOGERROR(
"VL6180 range sensor %s does not exist.", strKey.c_str());
1555 return -LAE_ECODE_BAD_VAL;
1560 uint_t &uRangeOffset,
1561 uint_t &uRangeCrossTalk,
1563 uint_t &uAlsIntPeriod)
1565 byte_t regRangeOffset;
1566 u16_t regRangeCrossTalk;
1568 u16_t regAlsIntPeriod;
1571 if( (i = keyIndex(strKey)) >= 0 )
1573 m_vecToF[i]->readShadowRegs(regRangeOffset, regRangeCrossTalk,
1574 regAlsGain, regAlsIntPeriod);
1576 uRangeOffset = (uint_t)regRangeOffset;
1577 uRangeCrossTalk = (uint_t)regRangeCrossTalk;
1580 uAlsIntPeriod = (uint)regAlsIntPeriod + 1;
1585 LOGERROR(
"VL6180 range sensor %s does not exist.", strKey.c_str());
1586 return -LAE_ECODE_BAD_VAL;
1590 int LaeVL6180MuxArray::keyIndex(
const string &strKey)
1592 for(
size_t i = 0; i <
m_vecToF.size(); ++i)
1594 if(
m_vecToF[i]->getNameId() == strKey )
1608 m_vecRanges(ToFSensorMaxNumOf, 0.0),
1609 m_vecLux(ToFSensorMaxNumOf, 0.0)
1613 pthread_mutex_init(&
m_mutex, NULL);
1618 pthread_mutex_destroy(&
m_mutex);
1645 for(
size_t i = 0; i <
m_vecLux.size(); ++i)
1653 LaeDesc::MapDescRangeSensor::const_iterator iter;
1654 SensorInfoMap::iterator iter2;
1664 uint_t uRangeOffset;
1665 uint_t uRangeCrossTalk;
1667 uint_t uAlsIntPeriod;
1672 string strRadiationType;
1687 LOGERROR(
"Failed to read ToFMux firmware version.");
1700 iter->second->m_nChan,
1701 iter->second->m_fDir,
1702 iter->second->m_fDeadzone,
1703 iter->second->m_strDesc);
1714 if( (rc =
cmdGetIdent(iter2->first, ident)) == LAE_OK )
1720 LOGERROR(
"VL6180 range %s sensor: Failed to read identify.",
1721 iter2->first.c_str());
1724 rc =
cmdGetTunes(iter2->first, uRangeOffset, uRangeCrossTalk,
1725 fAlsGain, uAlsIntPeriod);
1733 LOGERROR(
"VL6180 range %s sensor: Failed to read tune parameters.",
1734 iter2->first.c_str());
1737 nOffset = (s8_t)(uRangeOffset & 0xff);
1740 fFoV, fBeamDir, fMin, fMax);
1742 LOGDIAG2(
"VL6180 %s(%d) Sensor Info:\n" 1745 " Beam Direction: %.1lf degrees\n" 1747 " FoV: %.1lf degrees\n" 1748 " Min Distance: %.3lf meters\n" 1749 " MAx Distance: %.3lf meters\n" 1751 " Model: 0x%02x v%u.%u\n" 1753 " Date/Time: %u/%u\n" 1755 " ToF Offset: %d(%u)\n" 1756 " ToF Cross-Talk: %u\n" 1757 " ALS Gain: %.2lf\n" 1758 " ALS Int. Period: %u msec",
1759 iter2->first.c_str(), iter2->second.m_nIndex,
1760 iter2->first.c_str(),
1762 strRadiationType.c_str(),
1766 ident.idModel, ident.idModelRevMajor, ident.idModelRevMinor,
1767 ident.idModuleRevMajor, ident.idModuleRevMinor,
1768 ident.idDate, ident.idTime,
1769 nOffset, uRangeOffset,
1775 LOGDIAG2(
"Configured Range Sensor Group from robot description.");
1783 int nRangeCrossTalk;
1788 SensorInfoMap::iterator iter;
1793 fAlsGain, nAlsIntPeriod);
1802 (uint_t)nRangeCrossTalk);
1806 LOGDIAG3(
"VL6180 range sensor %s: Time-of-flight sensor tuned.",
1807 iter->first.c_str());
1811 LOGERROR(
"VL6180 range sensor %s: Failed to tune time-of-flight.",
1812 iter->first.c_str());
1820 rc =
cmdTuneAls(iter->first, fAlsGain, (uint_t)nAlsIntPeriod);
1824 LOGDIAG3(
"VL6180 range sensor %s: Ambient light sensor tuned.",
1825 iter->first.c_str());
1829 LOGERROR(
"VL6180 range sensor %s: Failed to tune ambient light sensor.",
1830 iter->first.c_str());
1835 LOGDIAG2(
"Tuned VL6180 range sensor group.");
1842 LOGDIAG2(
"Reloading VL6180 range sensor group tuning parameters...");
1853 #endif // LAE_USE_ALS 1858 byte_t cmd[LaeToFMuxI2CMaxCmdLen];
1859 byte_t rsp[LaeToFMuxI2CMaxRspLen];
1861 size_t lenRsp = LaeToFMuxI2CRspLenGetVersion;
1866 cmd[lenCmd++] = LaeToFMuxI2CCmdIdGetVersion;
1872 uVerNum = (uint_t)rsp[0];
1874 RtDb.m_product.m_uToFMuxFwVer =
m_uFwVer;
1885 byte_t cmd[LaeToFMuxI2CMaxCmdLen];
1886 byte_t rsp[LaeToFMuxI2CMaxRspLen];
1888 size_t lenRsp = LaeToFMuxI2CRspLenGetIdent;
1890 u16_t val_hi, val_lo;
1894 SensorInfoMap::iterator pos;
1898 LOGERROR(
"VL6180 sensor %s not found.", strKey.c_str());
1899 return -LAE_ECODE_BAD_VAL;
1902 sensorIndex = pos->second.m_nIndex;
1906 cmd[lenCmd++] = LaeToFMuxI2CCmdIdGetIdent;
1907 cmd[lenCmd++] = sensorIndex;
1914 ident.idModel = rsp[n++];
1915 ident.idModelRevMajor = rsp[n++];
1916 ident.idModelRevMinor = rsp[n++];
1917 ident.idModuleRevMajor = rsp[n++];
1918 ident.idModuleRevMinor = rsp[n++];
1920 val_hi = ((u16_t)rsp[n++]) << 8;
1921 val_lo = (u16_t)rsp[n++];
1922 ident.idDate = val_hi | val_lo;
1924 val_hi = ((u16_t)rsp[n++]) << 8;
1925 val_lo = (u16_t)rsp[n++];
1926 ident.idTime = val_hi | val_lo;
1936 byte_t cmd[LaeToFMuxI2CMaxCmdLen];
1937 byte_t rsp[LaeToFMuxI2CMaxRspLen];
1939 size_t lenRsp = LaeToFMuxI2CRspLenGetRanges;
1947 cmd[lenCmd++] = LaeToFMuxI2CCmdIdGetRanges;
1953 for(sensorIndex = 0; sensorIndex < ToFSensorMaxNumOf; ++sensorIndex)
1955 val = rsp[sensorIndex];
1956 if( val <= LaeToFMuxRangeMax )
1958 fRange = (double)val * 0.001;
1960 else if( val == LaeToFMuxRangeNoObj )
1964 else if( val == LaeToFMuxRangeNoDev )
1975 RtDb.m_range[sensorIndex].m_fRange = fRange;
1997 byte_t cmd[LaeToFMuxI2CMaxCmdLen];
1998 byte_t rsp[LaeToFMuxI2CMaxRspLen];
2000 size_t lenRsp = LaeToFMuxI2CRspLenGetLux;
2009 cmd[lenCmd++] = LaeToFMuxI2CCmdIdGetLux;
2017 for(sensorIndex = 0; sensorIndex < ToFSensorMaxNumOf; ++sensorIndex)
2020 for(
int i = 0; i < 4; ++i)
2026 fLux = (double)val * (
double)LaeToFMuxI2CArgLuxScale;
2028 RtDb.m_range[sensorIndex].m_fAmbientLight = fLux;
2050 uint_t &uRangeOffset,
2051 uint_t &uRangeCrossTalk,
2053 uint_t &uAlsIntPeriod)
2055 byte_t cmd[LaeToFMuxI2CMaxCmdLen];
2056 byte_t rsp[LaeToFMuxI2CMaxRspLen];
2058 size_t lenRsp = LaeToFMuxI2CRspLenGetTunes;
2061 uint_t val_hi, val_lo;
2065 SensorInfoMap::iterator pos;
2069 LOGERROR(
"VL6180 sensor %s not found.", strKey.c_str());
2070 return -LAE_ECODE_BAD_VAL;
2073 sensorIndex = pos->second.m_nIndex;
2077 cmd[lenCmd++] = LaeToFMuxI2CCmdIdGetTunes;
2078 cmd[lenCmd++] = sensorIndex;
2086 uRangeOffset = rsp[n++];
2090 val_hi = ((uint_t)rsp[n++]) << 8;
2091 val_lo = (uint_t)rsp[n++];
2092 uRangeCrossTalk = val_hi | val_lo;
2096 uRangeCrossTalk = rsp[n++];
2102 val_hi = ((uint_t)rsp[n++]) << 8;
2103 val_lo = (uint_t)rsp[n++];
2104 uAlsIntPeriod = val_hi | val_lo;
2113 uint_t uRangeOffset,
2114 uint_t uRangeCrossTalk)
2116 byte_t cmd[LaeToFMuxI2CMaxCmdLen];
2117 byte_t rsp[LaeToFMuxI2CMaxRspLen];
2119 size_t lenRsp = LaeToFMuxI2CRspLenTuneToFSensor;
2123 byte_t val_hi, val_lo;
2127 SensorInfoMap::iterator pos;
2131 LOGERROR(
"VL6180 sensor %s not found.", strKey.c_str());
2132 return -LAE_ECODE_BAD_VAL;
2135 sensorIndex = pos->second.m_nIndex;
2145 cmd[lenCmd++] = LaeToFMuxI2CCmdIdTuneToFSensor;
2146 cmd[lenCmd++] = sensorIndex;
2147 cmd[lenCmd++] = regOffset;
2151 val_hi = (byte_t)((regCrossTalk >> 8) & 0xff);
2152 val_lo = (byte_t)(regCrossTalk & 0xff);
2153 cmd[lenCmd++] = val_hi;
2154 cmd[lenCmd++] = val_lo;
2158 cmd[lenCmd++] = regCrossTalk;
2175 uint_t uAlsIntPeriod)
2177 byte_t cmd[LaeToFMuxI2CMaxCmdLen];
2178 byte_t rsp[LaeToFMuxI2CMaxRspLen];
2180 size_t lenRsp = LaeToFMuxI2CRspLenTuneAls;
2183 byte_t val_hi, val_lo;
2187 SensorInfoMap::iterator pos;
2191 LOGERROR(
"VL6180 sensor %s not found.", strKey.c_str());
2192 return -LAE_ECODE_BAD_VAL;
2195 sensorIndex = pos->second.m_nIndex;
2204 val_hi = (byte_t)((uAlsIntPeriod >> 8) & 0xff);
2205 val_lo = (byte_t)(uAlsIntPeriod & 0xff);
2207 cmd[lenCmd++] = LaeToFMuxI2CCmdIdTuneAls;
2208 cmd[lenCmd++] = sensorIndex;
2209 cmd[lenCmd++] = regAlsGain;
2210 cmd[lenCmd++] = val_hi;
2211 cmd[lenCmd++] = val_lo;
2227 SensorInfoMap::iterator pos;
2231 LOGERROR(
"VL6180 sensor %s not found.", strKey.c_str());
2232 return -LAE_ECODE_BAD_VAL;
2235 int sensorIndex = pos->second.m_nIndex;
2243 std::vector<double> &vecRanges)
2245 SensorInfoMap::iterator iter;
2252 vecNames.push_back(iter->first);
2253 vecRanges.push_back(
m_vecRanges[iter->second.m_nIndex]);
2261 SensorInfoMap::iterator pos;
2265 LOGERROR(
"VL6180 sensor %s not found.", strKey.c_str());
2266 return -LAE_ECODE_BAD_VAL;
2269 int sensorIndex = pos->second.m_nIndex;
2277 std::vector<double> &vecLux)
2279 SensorInfoMap::iterator iter;
2286 vecNames.push_back(iter->first);
2287 vecLux.push_back(
m_vecLux[iter->second.m_nIndex]);
2293 std::string &strRadiationType,
2299 SensorInfoMap::iterator pos;
2303 LOGERROR(
"VL6180 range sensor %s not found.", strKey.c_str());
2304 return -LAE_ECODE_BAD_VAL;
2310 std::string strDesc;
2312 pos->second.getProps(nIndex, nChan, strRadiationType, fFoV, fBeamDir,
2313 fDeadzone, fMin, fMax, strDesc);
2326 uint_t &uRangeOffset,
2327 uint_t &uRangeCrossTalk,
2329 uint_t &uAlsIntPeriod)
2331 return cmdGetTunes(strKey, uRangeOffset, uRangeCrossTalk,
2332 fAlsGain, uAlsIntPeriod);
2345 RtDb.m_enable.m_bRange =
true;
2359 RtDb.m_enable.m_bRange =
false;
2365 RtDb.m_enable.m_bRange =
true;
2438 string &strRadiationType,
2467 uint_t &uRangeOffset,
2468 uint_t &uRangeCrossTalk,
2470 uint_t &uAlsIntPeriod)
2475 fAlsGain, uAlsIntPeriod);
2480 uRangeCrossTalk = 0;
2494 vector<double> &vecRanges)
2507 vector<double> &vecAmbient)
uint_t m_uAlsIntPeriod
ALS integration period (msec)
#define VL6180X_AMBIENT_INT_T_MIN
minimum als int. period (msec)
pthread_mutex_t m_mutex
mutex
#define VL6180X_RANGE_MAX
maximum range (m)
Multiplexed range sensors class.
#define VL6180X_RANGE_XTALK_MIN
minimum tof cross-talk
void lock()
Lock the share resource.
vl6180x_als_gain
Ambient Light Sensor gain value enumeration.
virtual int getRange(const std::string &strKey, double &fRange)
Get the shadowed range measurement.
static const int AlsFreq
take an ambient measurement cycle rate
int cmdTuneAls(const std::string &strKey, double fAlsGain, uint_t uAlsIntPeriod)
Tune ambient light sensor command.
static const int NSenseErrorsThreshold
Consecutive sensed error count threshold.
virtual ~LaeVL6180Mux()
Destructor.
virtual void exec()
Execute task in one cycle to take measurements.
int cmdGetTunes(const std::string &strKey, uint_t &uRangeOffset, uint_t &uRangeCrossTalk, double &fAlsGain, uint_t &uAlsIntPeriod)
Read exported tuning parameters command.
Laelaps tuning data class.
int writeDefaults()
Write defaults to sensor.
#define VL6180X_RANGE_OFFSET_MAX
maximum tof offset
virtual int reload(const laelaps::LaeTunes &tunes)
Reload configuration tuning parameters.
virtual int getSensorProps(const std::string &strKey, std::string &strRadiationType, double &fFoV, double &fBeamDir, double &fMin, double &fMax)
Get range sensor properties.
number of gain enum values
virtual int getInterfaceVersion(uint_t &uVerMajor, uint_t &uVerMinor, uint_t &uFwVer)
Get interface version.
Laelaps robotic mobile platform full description class.
void clearSensedData()
Clear sensed data.
virtual int write_read(uint_t addr, const byte_t wbuf[], size_t wlen, byte_t rbuf[], size_t rlen, long usec=0)
Perform a write/read transaction to/from an I2C slave endpoint device.
LaeRangeInterface * m_interface
the interface
double degToRad(double d)
Convert degrees to radians.
int m_nAlsCounter
when zero, make measurement
u16_t m_regAlsIntPeriod
ALS itegration period register.
#define VL6180X_AMBIENT_INT_T_MAX
maximum als int. period (msec)
virtual int reload(const laelaps::LaeTunes &tunes)
Reload configuration tuning parameters.
static double AlsGainAnalogTbl[GAIN_NumOf]
Ambient Light Sensor gain table.
virtual int readSensorIdentity(const std::string &strKey, VL6180xIdentification &ident)
Read sensor's identification.
#define LAE_VER_MINOR(ver)
Get version minor number from version.
laelaps::LaeI2CMux & m_mux
I2C multiplexor.
int cmdGetAmbientLight()
Get ambient light measurments command.
int m_nAlsIndex
ambient light sensor index
double m_fAmbientLight
ambient light (lux)
laelaps::LaeI2C & m_i2cBus
bound I2C bus instance
virtual int configure(const laelaps::LaeDesc &desc)
Configure sensor array from product description.
virtual int getAmbientLight(const std::string &strKey, double &fAmbient)
Get an ambient light illuminance measurement.
double m_fDeadzone
sensor deadzone (m)
virtual int getSensorProps(const std::string &strKey, std::string &strRadiationType, double &fFoV, double &fBeamDir, double &fMin, double &fMax)
Get range sensor properties.
virtual int getInterfaceVersion(uint_t &uVerMajor, uint_t &uVerMinor, uint_t &uFwVer)
Get interface version.
virtual ~LaeVL6180MuxArray()
Destructor.
static vl6180x_als_gain gainAnalogToEnum(double fAlsGain)
Convert ambient light sensor analog gain to associated register value enum.
std::string m_strNameId
name identifier of sensor
Container class to hold VL6180 time-of-flight sensor static information.
virtual int cmdGetFwVersion(uint_t &uVerNum)
Get the firmware version command.
Laelaps PCA9548A I2C multiplexer switch interface.
int m_nChan
multiplexed channel number
#define VL6180X_ADDR
I2C 7-bit address.
#define VL6180X_AMBIENT_GAIN_MASK
als analog gain mask
virtual int getSensorProps(const std::string &strKey, std::string &strRadiationType, double &fFoV, double &fBeamDir, double &fMin, double &fMax)
Get range sensor properties.
VL6180 Time of Flight Class.
virtual int reload(const laelaps::LaeTunes &tunes)
Reload configuration tuning parameters.
u32_t waitForSensorMeasurement(u32_t msecWait, byte_t bitDone)
Wait for sensor measurement to complete.
int calibCrossTalk(int &nCrossTalk)
Calibrate cross-talk compensation.
byte_t m_regAlsGain
ambient light sensor gain register
std::vector< double > m_vecRanges
measured distances (meters)
pthread_mutex_t m_mutex
mutex
virtual void exec()
Execute task in one cycle to take measurements.
int writeReg16(u16_t reg, u16_t val)
Write a 16-bit value to a register.
int m_nErrorCnt
consecutive error count
void unlock()
Unlock the shared resource.
virtual int write(int chan, uint_t addr, byte_t buf[], size_t len)
Write from an I2C endpoint device.
virtual void exec()
Execute one cycle to take measurements.
double radToDeg(double r)
Convert radians to degrees.
std::string m_strDesc
short description
Range sensors interface base class.
int calibOffset(int &nOffsetPre, double &fAvgPre, int &nOffsetPost, double &fAvgPost)
Calibrate part-to-part offset.
#define VL6180X_RANGE_XTALK_MAX
maximum tof cross-talk
virtual int configure(const laelaps::LaeDesc &desc)
Configure sensor group from product description.
Laelaps Time-of-Flight sensors. The ToFs are used as a virtual bumper for close-in obstacle detection...
int initSensor(bool bForce=false)
Initialize sensor with recommended settings and defaults.
void getVL6180Params(const std::string &strName, int &nTofOffset, int &nTofCrossTalk, double &fAlsGain, int &nAlsIntPeriod) const
Get VL6180 range sensor tune parameters.
virtual int getInterfaceVersion(uint_t &uVerMajor, uint_t &uVerMinor, uint_t &uFwVer)
Get interface version.
LaeRangeSensorGroup(laelaps::LaeI2C &i2cBus)
Default constructor.
The <b><i>Laelaps</i></b> namespace encapsulates all <b><i>Laelaps</i></b> related constructs...
Laelaps robotic base mobile platform description class interface.
int readId(struct VL6180xIdentification &id)
Read sensor identification.
#define VL6180X_RANGE_NO_OBJ
no object detected
void readShadowRegs()
Read shadows register values and update derived data.
VecToFSensors m_vecToF
time of flight sensors
virtual void clearSensedData()
Clear sensed data.
virtual int getInterfaceVersion(uint_t &uVerMajor, uint_t &uVerMinor, uint_t &uFwVer)
Get interface version.
Laelaps common utilities.
virtual ~LaeRangeMuxSubproc()
Destructor.
int cap(int a, int min, int max)
Cap value within limits [min, max].
virtual void clearSensedData()
Clear sensed data.
#define VL6180X_T_AUTO
auto-determine wait time
void lock()
Lock the share resource.
virtual int readSensorIdentity(const std::string &strKey, VL6180xIdentification &ident)
Read sensor's identification.
void unlock()
Unlock the shared resource.
Laelaps built-in Time-of-Flight Multiplexer Arduino sub-processor interface.
virtual int readSensorIdentity(const std::string &strKey, VL6180xIdentification &ident)
Read sensor's identification.
~LaeRangeSensorGroup()
Destructor.
double m_fBeamDir
center of beam direction(radians)
int m_nChan
multiplexed channel number
LaeVL6180MuxArray(laelaps::LaeI2C &i2cBus)
Initialization constructor.
virtual void whitelist()
White list range sensor group from robot sensors.
#define VL6180X_ERR_MEAS
error meassurement
virtual int getAmbientLight(const std::string &strKey, double &fAmbient)
Get the shadowed ambient light illuminance measurement.
virtual int readSensorTunes(const std::string &strKey, uint_t &uRangeOffset, uint_t &uRangeCrossTalk, double &fAlsGain, uint_t &uAlsIntPeriod)
Read sensor's current tuning parameters.
virtual void blacklist()
Black list range sensor group from robot sensors.
virtual void exec()
Execute task in one cycle to take measurements.
static double gainEnumToAnalog(vl6180x_als_gain eAlsGain)
Convert ambient light sensor gain register value enum to analog gain.
double m_fAlsGain
ambient light sensor analog gain
LaeRangeMuxSubproc(laelaps::LaeI2C &i2cBus, uint_t addr=laelaps::LaeI2CAddrToFMux)
Initialization constructor.
uint_t m_uFwVer
firmware version number
bool m_bBlackListed
sensor group [not] black listed.
int setInterface(uint_t uProdHwVer)
Set the interface, given the <b><i>Laelaps</i></b> hardware version.
#define VL6180X_RANGE_OFFSET_MIN
minimum tof offset
int cmdTuneToFSensor(const std::string &strKey, uint_t uRangeOffset, uint_t uRangeCrossTalk)
Tune time-of-flight range sensor command.
virtual int readSensorTunes(const std::string &strKey, uint_t &uRangeOffset, uint_t &uRangeCrossTalk, double &fAlsGain, uint_t &uAlsIntPeriod)
Read sensor's current tuning parameters.
static const long TStd
standard wait write_read (usec)
#define LAE_VERSION(major, minor, revision)
Convert version triplet to integer equivalent.
int readReg8(u16_t reg, byte_t &val)
Read an 8-bit value from a register.
int readReg16(u16_t reg, u16_t &val)
Read a 16-bit value from a register.
bool m_bBlackListed
sensor is [not] black listed
virtual int readSensorTunes(const std::string &strKey, uint_t &uRangeOffset, uint_t &uRangeCrossTalk, double &fAlsGain, uint_t &uAlsIntPeriod)
Read sensor's current tuning parameters.
int writeReg8(u16_t reg, byte_t val)
Write an 8-bit value to a register.
virtual int configure(const laelaps::LaeDesc &desc)
Configure sensor array from product description.
#define LAE_VER_MAJOR(ver)
Get version major number from version.
virtual int getRange(const std::string &strKey, double &fRange)
Get the shadowed range measurement.
virtual void clearSensedData()
Clear sensed data.
u32_t waitForSensorReady(u16_t regStatus, u32_t msecWait)
Wait for sensor to be ready.
laelaps::LaeI2CMux m_mux
I2C multiplexor.
u16_t m_regRangeCrossTalk
range cross-talk register
virtual int reload(const laelaps::LaeTunes &tunes)
Reload configuration tuning parameters.
virtual bool isBlackListed()
Test if range sensor group is black listed.
SensorInfoMap m_mapInfo
map of sensor properties by key
int cmdGetIdent(const std::string &strKey, VL6180xIdentification &ident)
Read sensor identification command.
virtual int getAmbientLight(const std::string &strKey, double &fAmbient)
Get the shadowed ambient light illuminance measurement.
virtual int getRange(const std::string &strKey, double &fRange)
Get a range measurement.
laelaps::LaeI2C & m_i2cBus
bound I2C bus instance
uint_t m_addrSubProc
I2C sub-processor address.
#define VL6180X_RANGE_MIN
minimum range (m)
std::vector< double > m_vecLux
measured ambient light (lux)
virtual int getSensorProps(const std::string &strKey, std::string &strRadiationType, double &fFoV, double &fBeamDir, double &fMin, double &fMax)
Get range sensor properties.
virtual int getAmbientLight(const std::string &strKey, double &fAmbient)
Get an ambient light illuminance measurement.
double measureRange(u32_t msecWait=0xffff)
Measure the sensed target range.
virtual int transact(int chan, uint_t addr, const byte_t wbuf[], size_t wlen, byte_t rbuf[], size_t rlen, long usec=0)
Perform a write/read transaction to/from an I2C slave endpoint device.
double measureAmbientLight(u32_t msecWait=0xffff)
Measure the sensed ambient light illuminance.
int tune(uint_t uRangeOffset, uint_t uRangeCrossTalk, double fAlsGain, uint_t uAlsIntPeriod)
Tune sensor configuration.
virtual int readSensorIdentity(const std::string &strKey, VL6180xIdentification &ident)
Read sensor's identification.
Laelaps real-time "database".
#define VL6180X_RANGE_FOV
field of view (degrees)
int cmdGetRanges()
Get range distance measurments command.
virtual int readSensorTunes(const std::string &strKey, uint_t &uRangeOffset, uint_t &uRangeCrossTalk, double &fAlsGain, uint_t &uAlsIntPeriod)
Read sensor's current tuning parameters.
#define VL6180X_FACTORY_DFT
use factory default
VL6180 Time of Flight Array Class.
byte_t m_regRangeOffset
range part-to-part offset register
Top-level package include file.
int outOfResetInit()
Initialize sensor out-of-reset.
#define VL6180X_AMBIENT_INT_T_MASK
als integration period mask
virtual int getRange(const std::string &strKey, double &fRange)
Get a range measurement.
static const int LAE_OK
not an error, success
MapDescRangeSensor m_mapDescRangeSensor
range sensor descriptions
virtual int configure(const laelaps::LaeDesc &desc)
Configure sensor array from product description.