Skip to content

Commit

Permalink
Updated RPLIDAR support and updates from UxVCtrl V360
Browse files Browse the repository at this point in the history
  • Loading branch information
lebarsfa committed Jul 30, 2020
1 parent e31c30a commit 115ebf0
Show file tree
Hide file tree
Showing 24 changed files with 292 additions and 74 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,4 @@ TODO/
UpgradeOSUtils.bat
UpgradeHardware.bat
UpgradeDLL*
genproto*
15 changes: 15 additions & 0 deletions GetAllSupportedScanModesRPLIDAR.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function [result, scanmodeids, scanmodeuspersamples, scanmodemaxdistances, scanmodeanstypes, scanmodenames] = GetAllSupportedScanModesRPLIDAR(pRPLIDAR)

scanmodeids = repmat(int32(0), [16 1]);
scanmodeuspersamples = repmat(double(0), [16 1]);
scanmodemaxdistances = repmat(double(0), [16 1]);
scanmodeanstypes = repmat(int32(0), [16 1]);
scanmodenames = repmat('0', [16 64]);

pScanModeIDs = libpointer('int32Ptr', scanmodeids);
pScanModeusPerSamples = libpointer('doublePtr', scanmodeuspersamples);
pScanModeMaxDistances = libpointer('doublePtr', scanmodemaxdistances);
pScanModeAnsTypes = libpointer('int32Ptr', scanmodeanstypes);
pScanModeNames = cellstr(scanmodenames);

[result, rplidar, scanmodeids, scanmodeuspersamples, scanmodemaxdistances, scanmodeanstypes, scanmodenames] = calllib('hardwarex', 'GetAllSupportedScanModesRPLIDARx', pRPLIDAR, pScanModeIDs, pScanModeusPerSamples, pScanModeMaxDistances, pScanModeAnsTypes, pScanModeNames);
12 changes: 3 additions & 9 deletions GetInfoRequestRPLIDAR.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,12 @@
hardwareVersion = 0;
firmwareMajor = 0;
firmwareMinor = 0;
serialNumber = repmat('0', [1 32]);
serialNumber = [repmat(int8('0'), [1 32]) int8(0)];

pModelID = libpointer('int32Ptr', modelID);
pHardwareVersion = libpointer('int32Ptr', hardwareVersion);
pFirmwareMajor = libpointer('int32Ptr', firmwareMajor);
pFirmwareMinor = libpointer('int32Ptr', firmwareMinor);
SerialNumber = libpointer('voidPtr', [int8(serialNumber) 0]);
SerialNumber = char(serialNumber);

result = calllib('hardwarex', 'GetInfoRequestRPLIDARx', pRPLIDAR, pModelID, pHardwareVersion, pFirmwareMajor, pFirmwareMinor, SerialNumber);

modelID = pModelID.value;
hardwareVersion = pHardwareVersion.value;
firmwareMajor = pFirmwareMajor.value;
firmwareMinor = pFirmwareMinor.value;
serialNumber = char(SerialNumber.value);
[result, rplidar, modelID, hardwareVersion, firmwareMajor, firmwareMinor, serialNumber] = calllib('hardwarex', 'GetInfoRequestRPLIDARx', pRPLIDAR, pModelID, pHardwareVersion, pFirmwareMajor, pFirmwareMinor, SerialNumber);
15 changes: 15 additions & 0 deletions GetOtherScanDataResponseFromThreadRPLIDAR.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function [result, distances, angles, bNewScan] = GetOtherScanDataResponseFromThreadRPLIDAR(pRPLIDAR)

distances = repmat(0, [1 32]);
angles = repmat(0, [1 32]);
bNewScan = 0;

pDistances = libpointer('doublePtr', distances);
pAngles = libpointer('doublePtr', angles);
pbNewScan = libpointer('int32Ptr', bNewScan);

result = calllib('hardwarex', 'GetOtherScanDataResponseFromThreadRPLIDARx', pRPLIDAR, pDistances, pAngles, pbNewScan);

distances = pDistances.value;
angles = pAngles.value;
bNewScan = pbNewScan.value;
9 changes: 9 additions & 0 deletions GetTypicalScanModeRPLIDAR.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function [result, scanmodeid] = GetTypicalScanModeRPLIDAR(pRPLIDAR)

scanmodeid = 0;

pScanModeID = libpointer('int32Ptr', scanmodeid);

result = calllib('hardwarex', 'GetTypicalScanModeRPLIDARx', pRPLIDAR, pScanModeID);

scanmodeid = pScanModeID.value;
18 changes: 14 additions & 4 deletions NMEAProtocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,13 @@ inline int AnalyzeSentenceNMEA(char* buf, int buflen, char* talkerid, char* mnem
ComputeChecksumNMEA(buf, *psentencelen, checksum);
if ((toupper(buf[*psentencelen-2-nb_bytes_end]) != checksum[1])||(toupper(buf[*psentencelen-1-nb_bytes_end]) != checksum[2]))
{
PRINT_DEBUG_WARNING(("Warning : NMEA checksum error (computed \"%.3s\", found \"*%c%c\"). \n", checksum, buf[*psentencelen-2-nb_bytes_end], buf[*psentencelen-1-nb_bytes_end]));
*pnbBytesToDiscard = *psentencelen;
PRINT_DEBUG_MESSAGE_OSUTILS(("Warning : NMEA checksum error (computed \"%.3s\", found \"*%c%c\"). \n", checksum, buf[*psentencelen-2-nb_bytes_end], buf[*psentencelen-1-nb_bytes_end]));
//for (i = 0; i < buflen; i++) printf("%c", buf[i]);
//printf("\n");
//for (i = 0; i < buflen; i++) printf("0x%02x ", (unsigned)buf[i]);
//printf("\n");
//*pnbBytesToDiscard = *psentencelen;
*pnbBytesToDiscard = 1; // Not sure more than the start character can be discarded...
return EXIT_FAILURE;
}
}
Expand Down Expand Up @@ -488,8 +493,13 @@ inline int AnalyzeSentenceWithAddressNMEA(char* buf, int buflen, char* talkerid,
ComputeChecksumNMEA(buf, *psentencelen, checksum);
if ((buf[*psentencelen-2-nb_bytes_end] != checksum[1])||(buf[*psentencelen-1-nb_bytes_end] != checksum[2]))
{
PRINT_DEBUG_WARNING(("Warning : NMEA checksum error (computed \"%.3s\", found \"*%c%c\"). \n", checksum, buf[*psentencelen-2-nb_bytes_end], buf[*psentencelen-1-nb_bytes_end]));
*pnbBytesToDiscard = *psentencelen;
PRINT_DEBUG_MESSAGE_OSUTILS(("Warning : NMEA checksum error (computed \"%.3s\", found \"*%c%c\"). \n", checksum, buf[*psentencelen-2-nb_bytes_end], buf[*psentencelen-1-nb_bytes_end]));
//for (i = 0; i < buflen; i++) printf("%c", buf[i]);
//printf("\n");
//for (i = 0; i < buflen; i++) printf("0x%02x ", (unsigned)buf[i]);
//printf("\n");
//*pnbBytesToDiscard = *psentencelen;
*pnbBytesToDiscard = 1; // Not sure more than the start character can be discarded...
return EXIT_FAILURE;
}
}
Expand Down
12 changes: 6 additions & 6 deletions P33x.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ inline int InitP33x(P33X* pP33x)
buf = readbuf[6];
stat = readbuf[7];

//PRINT_DEBUG_MESSAGE(("Device ID : %d.%d\n", devclass, group));
//PRINT_DEBUG_MESSAGE(("Firmware version : %d.%d\n", year, week));
//PRINT_DEBUG_MESSAGE(("Length of the internal receive buffer : %d\n", buf));
//PRINT_DEBUG_MESSAGE(("Status information : %d\n", stat));
//PRINT_DEBUG_MESSAGE_OSUTILS(("Device ID : %d.%d\n", devclass, group));
//PRINT_DEBUG_MESSAGE_OSUTILS(("Firmware version : %d.%d\n", year, week));
//PRINT_DEBUG_MESSAGE_OSUTILS(("Length of the internal receive buffer : %d\n", buf));
//PRINT_DEBUG_MESSAGE_OSUTILS(("Status information : %d\n", stat));

return EXIT_SUCCESS;
}
Expand Down Expand Up @@ -202,8 +202,8 @@ inline int ReadChannelP33x(P33X* pP33x, uint8 Channel, float* pValue)

*pValue = value.v;

//PRINT_DEBUG_MESSAGE(("Channel value : %f\n", (double)*pValue));
//PRINT_DEBUG_MESSAGE(("Status information : %d\n", stat));
//PRINT_DEBUG_MESSAGE_OSUTILS(("Channel value : %f\n", (double)*pValue));
//PRINT_DEBUG_MESSAGE_OSUTILS(("Status information : %d\n", stat));

return EXIT_SUCCESS;
}
Expand Down
125 changes: 89 additions & 36 deletions RPLIDAR.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ using namespace rp::standalone::rplidar;
#define MEASUREMENT_CAPSULED_RESPONSE_RPLIDAR 0x82 // Added in FW ver 1.17.
#define SAMPLERATE_RESPONSE_RPLIDAR 0x15 // Added in FW ver 1.17.
#define ACC_BOARD_FLAG_RESPONSE_RPLIDAR 0xFF
#else
#endif // !ENABLE_RPLIDAR_SDK_SUPPORT

#define NB_BYTES_SERIAL_NUMBER_RPLIDAR 16
Expand Down Expand Up @@ -131,6 +132,18 @@ using namespace rp::standalone::rplidar;

#define MAX_NB_MEASUREMENTS_PER_SCAN_RPLIDAR 8192

#define MAX_NB_SCAN_MODES_RPLIDAR 16

struct RPLIDARSCANMODE
{
int id;
double us_per_sample;
double max_distance;
int ans_type;
char scan_mode[64];
};
typedef struct RPLIDARSCANMODE RPLIDARSCANMODE;

#pragma endregion
struct RPLIDAR
{
Expand Down Expand Up @@ -842,6 +855,57 @@ inline int GetSampleRateRequestRPLIDAR(RPLIDAR* pRPLIDAR, int* pTstandard, int*
#endif // ENABLE_RPLIDAR_SDK_SUPPORT
}

inline int GetTypicalScanModeRPLIDAR(RPLIDAR* pRPLIDAR, int* pScanModeID)
{
#ifdef ENABLE_RPLIDAR_SDK_SUPPORT
_u16 scanmodeid = 0;

if (IS_FAIL(pRPLIDAR->drv->getTypicalScanMode(scanmodeid)))
{
printf("A RPLIDAR is not responding correctly : getTypicalScanMode() failed. \n");
return EXIT_FAILURE;
}
*pScanModeID = (int)scanmodeid;
return EXIT_SUCCESS;
#else
UNREFERENCED_PARAMETER(pRPLIDAR);
UNREFERENCED_PARAMETER(pScanModeID);
printf("RPLIDAR : Not implemented. \n");
return EXIT_NOT_IMPLEMENTED;
#endif // ENABLE_RPLIDAR_SDK_SUPPORT
}

// MAX_NB_SCAN_MODES_RPLIDAR scanmodes...
inline int GetAllSupportedScanModesRPLIDAR(RPLIDAR* pRPLIDAR, RPLIDARSCANMODE* pScanModes)
{
#ifdef ENABLE_RPLIDAR_SDK_SUPPORT
std::vector<RplidarScanMode> outModes;
unsigned int i = 0;

if (IS_FAIL(pRPLIDAR->drv->getAllSupportedScanModes(outModes)))
{
printf("A RPLIDAR is not responding correctly : getAllSupportedScanModes() failed. \n");
return EXIT_FAILURE;
}
if (outModes.size() > MAX_NB_SCAN_MODES_RPLIDAR) printf("Warning : RPLIDAR unsupported scanmodes. \n");
memset(pScanModes, 0, sizeof(RPLIDARSCANMODE)*MAX_NB_SCAN_MODES_RPLIDAR);
for (i = 0; i < min(outModes.size(), MAX_NB_SCAN_MODES_RPLIDAR); i++)
{
pScanModes[i].id = (int)outModes[i].id;
pScanModes[i].us_per_sample = (double)outModes[i].us_per_sample;
pScanModes[i].max_distance = (double)outModes[i].max_distance;
pScanModes[i].ans_type = (int)outModes[i].ans_type;
memcpy(pScanModes[i].scan_mode, outModes[i].scan_mode, sizeof(pScanModes[i].scan_mode));
}
return EXIT_SUCCESS;
#else
UNREFERENCED_PARAMETER(pRPLIDAR);
UNREFERENCED_PARAMETER(pScanModes);
printf("RPLIDAR : Not implemented. \n");
return EXIT_NOT_IMPLEMENTED;
#endif // ENABLE_RPLIDAR_SDK_SUPPORT
}

// Undocumented...
inline int CheckMotorControlSupportRequestRPLIDAR(RPLIDAR* pRPLIDAR)
{
Expand Down Expand Up @@ -1241,20 +1305,19 @@ inline int GetExpressScanDataResponseRPLIDAR(RPLIDAR* pRPLIDAR, double* pDistanc
return EXIT_SUCCESS;
}

inline int StartOtherScanRequestRPLIDAR(RPLIDAR* pRPLIDAR, int scanmode)
inline int StartOtherScanRequestRPLIDAR(RPLIDAR* pRPLIDAR, int scanmodeid)
{
#ifdef ENABLE_RPLIDAR_SDK_SUPPORT
if (IS_FAIL(pRPLIDAR->drv->startScanExpress(false, (_u16)scanmode)))
if (IS_FAIL(pRPLIDAR->drv->startScanExpress(false, (_u16)scanmodeid)))
{
printf("A RPLIDAR is not responding correctly : startScanExpress() failed. \n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
#else
UNREFERENCED_PARAMETER(pRPLIDAR);
UNREFERENCED_PARAMETER(scanmode);
printf("RPLIDAR : Not implemented. \n");
return EXIT_NOT_IMPLEMENTED;
UNREFERENCED_PARAMETER(scanmodeid);
printf("RPLIDAR : Not implemented, defaulting to SCAN. \n");
return StartScanRequestRPLIDAR(pRPLIDAR);
#endif // ENABLE_RPLIDAR_SDK_SUPPORT
}

Expand Down Expand Up @@ -1302,12 +1365,24 @@ inline int GetOtherScanDataResponseRPLIDAR(RPLIDAR* pRPLIDAR, double* pDistances

return EXIT_SUCCESS;
#else
UNREFERENCED_PARAMETER(pRPLIDAR);
UNREFERENCED_PARAMETER(pDistances);
UNREFERENCED_PARAMETER(pAngles);
UNREFERENCED_PARAMETER(pbNewScan);
printf("RPLIDAR : Not implemented. \n");
return EXIT_NOT_IMPLEMENTED;
int j = 0;

for (j = 0; j < NB_MEASUREMENTS_OTHER_SCAN_DATA_RESPONSE_RPLIDAR; j++)
{
double distance = 0, angle = 0;
BOOL bNewScan = FALSE;
int quality = 0;

if (GetScanDataResponseRPLIDAR(pRPLIDAR, &distance, &angle, &bNewScan, &quality) != EXIT_SUCCESS)
{
return EXIT_FAILURE;
}
*pbNewScan = (*pbNewScan) | (bNewScan);
pAngles[j] = angle;
pDistances[j] = distance;
}

return EXIT_SUCCESS;
#endif // ENABLE_RPLIDAR_SDK_SUPPORT
}

Expand Down Expand Up @@ -1549,18 +1624,7 @@ inline int ConnectRPLIDAR(RPLIDAR* pRPLIDAR, char* szCfgFilePath)
// return EXIT_FAILURE;
//}

if (SetMotorPWMRequestRPLIDAR(pRPLIDAR, DEFAULT_MOTOR_PWM_RPLIDAR) != EXIT_SUCCESS)
{
printf("Unable to connect to a RPLIDAR : SET_MOTOR_PWM failure.\n");
#ifdef ENABLE_RPLIDAR_SDK_SUPPORT
pRPLIDAR->drv->stopMotor();
pRPLIDAR->drv->disconnect();
RPlidarDriver::DisposeDriver(pRPLIDAR->drv); pRPLIDAR->drv = NULL;
#else
CloseRS232Port(&pRPLIDAR->RS232Port);
#endif // ENABLE_RPLIDAR_SDK_SUPPORT
return EXIT_FAILURE;
}
SetMotorPWMRequestRPLIDAR(pRPLIDAR, DEFAULT_MOTOR_PWM_RPLIDAR);

memset(pRPLIDAR->esdata_prev, 0, sizeof(pRPLIDAR->esdata_prev));
switch (pRPLIDAR->ScanMode)
Expand Down Expand Up @@ -1652,18 +1716,7 @@ inline int DisconnectRPLIDAR(RPLIDAR* pRPLIDAR)
return EXIT_FAILURE;
}

if (SetMotorPWMRequestRPLIDAR(pRPLIDAR, 0) != EXIT_SUCCESS)
{
printf("Error while disconnecting a RPLIDAR.\n");
#ifdef ENABLE_RPLIDAR_SDK_SUPPORT
pRPLIDAR->drv->stopMotor();
pRPLIDAR->drv->disconnect();
RPlidarDriver::DisposeDriver(pRPLIDAR->drv); pRPLIDAR->drv = NULL;
#else
CloseRS232Port(&pRPLIDAR->RS232Port);
#endif // ENABLE_RPLIDAR_SDK_SUPPORT
return EXIT_FAILURE;
}
SetMotorPWMRequestRPLIDAR(pRPLIDAR, 0);

#ifdef ENABLE_RPLIDAR_SDK_SUPPORT
pRPLIDAR->drv->stopMotor();
Expand Down
2 changes: 1 addition & 1 deletion RPLIDAR0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ COM9
1
% bStartScanModeAtStartup
1
% ScanMode (0 : SCAN, 1 : EXPRESS_SCAN, 2 : FORCE_SCAN)
% ScanMode (0 : SCAN, 1 : EXPRESS_SCAN, 2 : FORCE_SCAN, or if using GetOtherScanDataResponseRPLIDAR(), the available values and modes might be different, see https://github.com/ENSTABretagneRobotics/Hardware-MATLAB/issues/3#issuecomment-661349278)
0
% motordelay (in ms)
2000
Expand Down
2 changes: 2 additions & 0 deletions SBG.h
Original file line number Diff line number Diff line change
Expand Up @@ -1251,6 +1251,8 @@ inline int ConnectSBG(SBG* pSBG, char* szCfgFilePath)
}
#endif // DISABLE_SBG_TCP

mSleep(500); // Needed sometimes to allow non-blocking sockets to be ready...

if (sbgEComInit(&pSBG->comHandle, &pSBG->sbgInterface) != SBG_NO_ERROR)
{
printf("Unable to connect to a SBG : Unable to initialize the sbgECom library.\n");
Expand Down
4 changes: 2 additions & 2 deletions StartOtherScanRequestRPLIDAR.m
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
function [result] = StartOtherScanRequestRPLIDAR(pRPLIDAR, scanmode)
result = calllib('hardwarex', 'StartOtherScanRequestRPLIDARx', pRPLIDAR, scanmode);
function [result] = StartOtherScanRequestRPLIDAR(pRPLIDAR, scanmodeid)
result = calllib('hardwarex', 'StartOtherScanRequestRPLIDARx', pRPLIDAR, scanmodeid);
2 changes: 2 additions & 0 deletions StartOtherScanThreadRPLIDAR.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
function [result] = StartOtherScanThreadRPLIDAR(pRPLIDAR)
result = calllib('hardwarex', 'StartOtherScanThreadRPLIDARx', pRPLIDAR);
2 changes: 2 additions & 0 deletions StopOtherScanThreadRPLIDAR.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
function [result] = StopOtherScanThreadRPLIDAR(pRPLIDAR)
result = calllib('hardwarex', 'StopOtherScanThreadRPLIDARx', pRPLIDAR);
20 changes: 13 additions & 7 deletions TODO.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
For rebuild, always check defines (to reset after build except for 3rd release), mavlink version (to reset after build), UpgradeDLL.bat, genproto...

Update Hardware-CPP, MATLAB, Python (check structures), in particular mavlink messages...

critical sections should be everywhere especially for Pololu and SSC32...
char/array of char parameters : see GetInfoRequestRPLIDAR(), GetAllSupportedScanModesRPLIDAR...


Script that copy downloaded drafts, put them in hardwarex_with_3rd_support, change defines and mavlink, run genproto, patch it (in a vm/docker with MATLAB 32 and 64?)...
patch hardwarex_proto.m for structures indicated in warnings...
https://fr.mathworks.com/matlabcentral/answers/103180-why-do-i-get-warnings-when-loading-a-dll-with-loadlibrary-in-matlab-7-13-r2011b
sed FcnPtr, s_LIST_ENTRYPtr voidPtr
Bitfields 'error' in UBX, so that UBX could be supported at least in MATLAB...
Fix also for latest mavlink MAVPACKED mavlink_types.h (check if it is also a problem for Linux) and auto test with sitl?
http://fr.mathworks.com/help/matlab/matlab_external/limitations-to-shared-library-support.html

RPLIDAR : Ne marche pas avec appli du fabricant parfois, on peut pas renommer le port car une autre application l'utilise, mais quelle autre...? Faut utiliser vieux SDK, et il faudrait que le code CPP r�cup�re les donn�es tout le temps dans un thread...
Crash matlab when exiting getotherscan...?
BSOD?

For rebuild, always check defines (to reset after build), mavlink version, update proto.m...

Probl�me parsing UBXProtocol.h (bitfields?) : �diter manuellement hardwarex_proto.m, faire un ifdef sp�cial cas MATLAB...?
http://fr.mathworks.com/help/matlab/matlab_external/limitations-to-shared-library-support.html
critical sections should be everywhere especially for Pololu and SSC32...

For the thread, only 1 device of the same type can be used...
Simplify by gathering Create, Connect...?
Expand All @@ -21,5 +29,3 @@ OLD
libhardwarex.so vs hardwarex.so...?

hardwarex_setup->error rplidar sdk C++->tweak rplidar struct (add padding when not using sdk?) so that size corresponds...?

Hardware-MATLAB/Python : if ENABLE_SBG_SDK_SUPPORT disabled, SBG MATLAB and Python functions should not be disabled...
Loading

0 comments on commit 115ebf0

Please sign in to comment.