-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
S3 RPLIDAR Does Not Respond to Changes in Motor PWM #5
Comments
Just checked with the RPLIDAR SDK on Linux (Ubuntu 16.04) A3 pwm/rpm can be changed. Another thing is that I am trying to expose Basically: It doesn't seem to touch anything SDK related, but errors out here: /*
Get the input queue length on the computer RS232 port.
HANDLE hDev : (IN) Identifier of the computer RS232 port.
int count : (OUT) bytes in input queue.
Return : EXIT_SUCCESS if no error or EXIT_FAILURE if there is an error.
*/
inline int GetFIFOComputerRS232Port(HANDLE hDev, int* count)
{
#ifdef _WIN32
COMSTAT stats;
memset(&stats, 0, sizeof(COMSTAT));
if (ClearCommError(hDev, NULL, &stats))
{
*count = stats.cbInQue;
return EXIT_SUCCESS;
}
else
{
return EXIT_FAILURE;
}
#else
int bytes_avail = 0;
if (ioctl((intptr_t)hDev, FIONREAD, &bytes_avail) != EXIT_SUCCESS)
{
PRINT_DEBUG_ERROR_OSCOMPUTERRS232PORT(("CheckAvailableBytesComputerRS232Port error (%s) : %s(hDev=%#x)\n",
strtime_m(),
GetLastErrorMsg(),
hDev));
return EXIT_FAILURE;
}
else
{
*count = bytes_avail;
return EXIT_SUCCESS;
}
#endif // _WIN32
} |
I did not have the time to check in details but about the pwm/rpm, I agree with what you say (I was more or less implying that in #3 (comment), i.e. About |
As always, thank you for responding to this issue. And again, if happen to have a BuyMeCoffee account I can add to or something, let me know. Your responses have been more than helpful. I must have missed the S1 only working with RPM and now PWM commands. This makes sense since using the frame grabber, and debugging it with VS code (attaching) I was able to see that setting pWM value will hit the speed endpoint. So I attached the frame_grabber.exe to debug and I know the Rplidar SDK works and is able to manipulate the S1. The using the SDK handle is a really good lead giving that the added GetFIFO Endpoint doesn’t reference the SDK and is based on some pre-SDK version Of your repo. The GetFIFO endpoint works without the SDK, which is more of an indicator of that I think. Let me give it a shot and report back! |
Well, As far as our custom added inline int GetFIFORPLIDAR(RPLIDAR* pRPLIDAR, int* count)
{
RS232PORT* pRS232Port = &pRPLIDAR->drv->_chanDev->_rxtxSerial->_serial_handle;
return GetFIFOComputerRS232Port(pRS232Port, count);
} The issue is that the I think the reference to [rplidar_driver_serial.h]
class SerialChannelDevice :public ChannelDevice
{
public:
rp::hal::serial_rxtx * _rxtxSerial;
bool _closePending;
SerialChannelDevice():_rxtxSerial(rp::hal::serial_rxtx::CreateRxTx()){}
bool bind(const char * portname, uint32_t baudrate)
{
_closePending = false;
return _rxtxSerial->bind(portname, baudrate);
}
bool open()
{
return _rxtxSerial->open();
}
void close()
{
_closePending = true;
_rxtxSerial->cancelOperation();
_rxtxSerial->close();
}
void flush()
{
_rxtxSerial->flush(0);
}
bool waitfordata(size_t data_count,_u32 timeout = -1, size_t * returned_size = NULL)
{
if (_closePending) return false;
return (_rxtxSerial->waitfordata(data_count, timeout, returned_size) == rp::hal::serial_rxtx::ANS_OK);
}
int senddata(const _u8 * data, size_t size)
{
return _rxtxSerial->senddata(data, size) ;
}
int recvdata(unsigned char * data, size_t size)
{
size_t lenRec = 0;
lenRec = _rxtxSerial->recvdata(data, size);
return lenRec;
}
void setDTR()
{
_rxtxSerial->setDTR();
}
void clearDTR()
{
_rxtxSerial->clearDTR();
}
void ReleaseRxTx()
{
rp::hal::serial_rxtx::ReleaseRxTx(_rxtxSerial);
}
}; So when debugging
This all is probably my lack of knowledge of C++ programming ... |
Yes, it seems due to C++ inheritance things that are blocking that (see e.g. https://stackoverflow.com/questions/19501838/get-derived-type-via-base-class-virtual-function). I quickly tried something like rp::standalone::rplidar::SerialChannelDevice* pscd = dynamic_cast<rp::standalone::rplidar::SerialChannelDevice*>(drv->_chanDev);
rp::arch::net::raw_serial* prs = dynamic_cast<rp::arch::net::raw_serial*>(pscd->_rxtxSerial); Then there is a problem with namespace rp {
namespace arch {
namespace net {
class raw_raw_serial : public raw_serial {
public:
raw_raw_serial(raw_serial rs) : raw_serial(rs) {}
HANDLE get_serial_handle()
{
//return this->raw_serial::_serial_handle;
return this->_serial_handle;
}
};
}
}
} so that then we can do rp::arch::net::raw_raw_serial rrs = *prs;
HANDLE hDev = rrs.get_serial_handle(); and then it should be possible to call Windows API functions using #include "arch/win32/arch_win32.h"
#include "arch/win32/net_serial.h"
#include "hal/abs_rxtx.h"
#include "hal/thread.h"
#include "hal/types.h"
#include "hal/assert.h"
#include "hal/locker.h"
#include "hal/socket.h"
#include "hal/event.h"
#include "rplidar_driver_impl.h"
#include "rplidar_driver_serial.h" |
To be honest, I don't think I could have figured that out ... So here is how I implemented it and it ALMOST works
// Getting the length of the FIFO on the RS232 serial port
inline int GetFIFORPLIDAR(RPLIDAR* pRPLIDAR, int* count)
{
rp::standalone::rplidar::SerialChannelDevice* pscd = dynamic_cast<rp::standalone::rplidar::SerialChannelDevice*>(pRPLIDAR->drv->_chanDev);
rp::arch::net::raw_serial* prs = dynamic_cast<rp::arch::net::raw_serial*>(pscd->_rxtxSerial);
rp::arch::net::raw_raw_serial rrs = *prs;
HANDLE hDev = rrs.get_serial_handle();
return GetFIFOComputerRS232Port(rrs.get_serial_handle(), count);
}
#include "arch/win32/arch_win32.h"
#include "arch/win32/net_serial.h"
#include "hal/abs_rxtx.h"
#include "hal/thread.h"
#include "hal/types.h"
#include "hal/assert.h"
#include "hal/locker.h"
#include "hal/socket.h"
#include "hal/event.h"
#include "rplidar_cmd.h"
#include "rplidar_driver.h"
#include "rplidar_driver_impl.h"
#include "rplidar_driver_serial.h"
Here is where I am getting an error that was odd:
Which is coming from #ifndef __cplusplus
#error "The RPlidar SDK requires a C++ compiler to be built"
#endif I initially thought that somehow the C++ compiler wasn't set up so I ran
Checking the Visual Studio code project, the linkers seem to be pointing to where the SDK outputted the static library. If i get rid of the block of code in the SDK with the |
I am not sure what is happening, maybe it is related to the order or place of the #include "../include/rplidar.h"
using namespace rp::standalone::rplidar; with #include "../include/rplidar.h"
//#include "arch/win32/arch_win32.h"
#include "arch/win32/net_serial.h"
#include "hal/abs_rxtx.h"
#include "hal/thread.h"
//#include "hal/types.h"
//#include "hal/assert.h"
#include "hal/locker.h"
//#include "hal/socket.h"
#include "hal/event.h"
#include "rplidar_driver_impl.h"
#include "rplidar_driver_serial.h"
// Because _serial_handle is protected...
namespace rp {
namespace arch {
namespace net {
class raw_raw_serial : public raw_serial {
public:
raw_raw_serial(raw_serial rs) : raw_serial(rs) {}
HANDLE get_serial_handle()
{
//return this->raw_serial::_serial_handle;
return this->_serial_handle;
}
};
}
}
}
using namespace rp::standalone::rplidar; and then as a test I tried to replace if (IS_FAIL(pRPLIDAR->drv->stop()))
{
printf("A RPLIDAR is not responding correctly : stop() failed. \n");
return EXIT_FAILURE;
} with rp::standalone::rplidar::SerialChannelDevice* pscd = dynamic_cast<rp::standalone::rplidar::SerialChannelDevice*>(pRPLIDAR->drv->_chanDev);
rp::arch::net::raw_serial* prs = dynamic_cast<rp::arch::net::raw_serial*>(pscd->_rxtxSerial);
//rp::arch::net::raw_raw_serial rrs = rp::arch::net::raw_raw_serial(*prs);
//HANDLE hDev = rrs.get_serial_handle();
HANDLE hDev = prs->_serial_handle;
unsigned char reqbuf[] = {0xA5,0x25};
// Send request.
if (WriteAllComputerRS232Port(hDev, reqbuf, sizeof(reqbuf)) != EXIT_SUCCESS)
{
printf("Error writing data to a RPLIDAR. \n");
return EXIT_FAILURE;
} in |
Also, did you run also |
I did not run I'm about to tinker with your updated suggestions and see if I can get it to work ... |
Well I think it was the position of the I also tried changing those SDK class properties that include Tried adding the extra class to I was able to build both, hardwarex and the SDK, (changing things every which way), and it looks like the reference to the handle seems off. I get this from MATLAB when running
which seems to be that reference (tried the commented out code as well) rp::standalone::rplidar::SerialChannelDevice* pscd = dynamic_cast<rp::standalone::rplidar::SerialChannelDevice*>(pRPLIDAR->drv->_chanDev);
rp::arch::net::raw_serial* prs = dynamic_cast<rp::arch::net::raw_serial*>(pscd->_rxtxSerial);
//rp::arch::net::raw_raw_serial rrs = rp::arch::net::raw_raw_serial(*prs);
//HANDLE hDev = rrs.get_serial_handle();
HANDLE hDev = prs->_serial_handle;
return GetFIFOComputerRS232Port(hDev, count); So tried it on linux, and linux def doesn't like it since the reference seems to be different in its bool open(const char * portname, uint32_t baudrate, uint32_t flags = 0);
void _init();
char _portName[200];
uint32_t _baudrate;
uint32_t _flags;
int serial_fd;
size_t required_tx_cnt;
size_t required_rx_cnt;
int _selfpipe[2];
bool _operation_aborted; Ultimately we are using the LIDAR in Linux. I wasn't initially aware until now that the reference would only work on Windows, given that the Windows serial port handle is: bool open(const char * portname, _u32 baudrate, _u32 flags);
void _init();
char _portName[20];
uint32_t _baudrate;
uint32_t _flags;
OVERLAPPED _ro, _wo;
OVERLAPPED _wait_o;
HANDLE _serial_handle;
DCB _dcb;
COMMTIMEOUTS _co; Would the serial port reference for linux be |
Yes, for Linux it is very likely to be namespace rp {
namespace arch {
namespace net {
class raw_raw_serial : public raw_serial {
public:
raw_raw_serial(raw_serial rs) : raw_serial(rs) {}
HANDLE get_serial_handle()
{
//return this->raw_serial::_serial_handle;
return this->_serial_handle;
}
};
}
}
} in case that part is causing problems, otherwise I would say you have to play with the order/place of the includes and maybe add or remove some includes from some SDK files... |
So maybe So with everything in place, either with the rp::standalone::rplidar::SerialChannelDevice* pscd = dynamic_cast<rp::standalone::rplidar::SerialChannelDevice*>(pRPLIDAR->drv->_chanDev);
rp::arch::net::raw_serial* prs = dynamic_cast<rp::arch::net::raw_serial*>(pscd->_rxtxSerial);
rp::arch::net::raw_raw_serial rrs = *prs;
HANDLE hDev = rrs.get_serial_handle();
return GetFIFOComputerRS232Port(hDev, count); That is, any combination of that block of code commented or not commented. So if any of that is used, it throws errors. Than when running
I definitely need to study up on this more, because those references and dynamic_casting is pretty foreign to me |
About |
Thanks for the swift response again. |
Question: So you mentioned you are running MATLAB R2017b, what compiler are you using with matlab's loadlibrary function to compile the interface files on Linux? I'm getting a MATLAB compile error on the the The MATLAB docs say that for MATLAB R2018b, the recommend GCC 6.3.x versions. When running I will upgrade and try it out ... |
The prebuilt #include "../include/rplidar.h"
using namespace rp::standalone::rplidar; with #include "../include/rplidar.h"
#ifdef _WIN32
//#include "arch/win32/arch_win32.h"
#include "arch/win32/net_serial.h"
#else
//#include "arch/linux/arch_linux.h"
#include "arch/linux/net_serial.h"
#endif // _WIN32
#include "hal/abs_rxtx.h"
#include "hal/thread.h"
//#include "hal/types.h"
//#include "hal/assert.h"
#include "hal/locker.h"
//#include "hal/socket.h"
#include "hal/event.h"
#include "rplidar_driver_impl.h"
#include "rplidar_driver_serial.h"
// Because _serial_handle is protected...
namespace rp {
namespace arch {
namespace net {
class raw_raw_serial : public raw_serial {
public:
raw_raw_serial(raw_serial rs) : raw_serial(rs) {}
#ifdef _WIN32
HANDLE get_serial_handle()
{
//return this->raw_serial::_serial_handle;
return this->_serial_handle;
}
#else
int get_serial_fd()
{
//return this->raw_serial::serial_fd;
return this->serial_fd;
}
#endif // _WIN32
};
}
}
}
using namespace rp::standalone::rplidar; (note that the part if (IS_FAIL(pRPLIDAR->drv->stop()))
{
printf("A RPLIDAR is not responding correctly : stop() failed. \n");
return EXIT_FAILURE;
} with rp::standalone::rplidar::SerialChannelDevice* pscd = dynamic_cast<rp::standalone::rplidar::SerialChannelDevice*>(pRPLIDAR->drv->_chanDev);
rp::arch::net::raw_serial* prs = dynamic_cast<rp::arch::net::raw_serial*>(pscd->_rxtxSerial);
//rp::arch::net::raw_raw_serial rrs = rp::arch::net::raw_raw_serial(*prs);
#ifdef _WIN32
//HANDLE hDev = rrs.get_serial_handle();
HANDLE hDev = prs->_serial_handle;
#else
//int hDev = rrs.get_serial_fd();
int hDev = prs->serial_fd;
#endif // _WIN32
unsigned char reqbuf[] = {0xA5,0x25};
// Send request.
if (WriteAllComputerRS232Port(hDev, reqbuf, sizeof(reqbuf)) != EXIT_SUCCESS)
{
printf("Error writing data to a RPLIDAR. \n");
return EXIT_FAILURE;
} in |
Well... without my additional So here is what I have before any changes: // Getting the length of the FIFO on the RS232 serial port, this is fine without the SDK obviously.
inline int GetFIFORPLIDAR(RPLIDAR* pRPLIDAR, int* count)
{
RS232PORT* pRS232Port = &pRPLIDAR->RS232Port;
return GetFIFOComputerRS232Port(pRS232Port->hDev, count);
} And here is what does not work: inline int GetFIFORPLIDAR(RPLIDAR* pRPLIDAR, int* count)
{
rp::standalone::rplidar::SerialChannelDevice* pscd = dynamic_cast<rp::standalone::rplidar::SerialChannelDevice*>(pRPLIDAR->drv->_chanDev);
rp::arch::net::raw_serial* prs = dynamic_cast<rp::arch::net::raw_serial*>(pscd->_rxtxSerial);
//rp::arch::net::raw_raw_serial rrs = rp::arch::net::raw_raw_serial(*prs);
#ifdef _WIN32
//HANDLE hDev = rrs.get_serial_handle();
HANDLE hDev = prs->_serial_handle;
#else
//int hDev = rrs.get_serial_fd();
int hDev = prs->serial_fd;
#endif // _WIN32
return GetFIFOComputerRS232Port(hDev, count);
} Getting this error in the second instance:
I think there is something small missing here ... Let me hack at it some more ... |
Well.... so I did the following (emulating what the other methods are doing) and it compiles fine and runs fine... returns the count. // Getting the length of the FIFO on the RS232 serial port
inline int GetFIFORPLIDAR(RPLIDAR* pRPLIDAR, int* count)
{
#ifdef ENABLE_RPLIDAR_SDK_SUPPORT
rp::standalone::rplidar::SerialChannelDevice* pscd = dynamic_cast<rp::standalone::rplidar::SerialChannelDevice*>(pRPLIDAR->drv->_chanDev);
rp::arch::net::raw_serial* prs = dynamic_cast<rp::arch::net::raw_serial*>(pscd->_rxtxSerial);
//rp::arch::net::raw_raw_serial rrs = rp::arch::net::raw_raw_serial(*prs);
#ifdef _WIN32
//HANDLE hDev = rrs.get_serial_handle();
HANDLE hDev = prs->_serial_handle;
#else
//int hDev = rrs.get_serial_fd();
int hDev = prs->serial_fd;
#endif // _WIN32
// Get the FIFO form the Port
return GetFIFOComputerRS232Port(hDev, count
#else
RS232PORT* pRS232Port = &pRPLIDAR->RS232Port;
return GetFIFOComputerRS232Port(pRS232Port->hDev, count)
#endif // ENABLE_RPLIDAR_SDK_SUPPORT
} |
Yeah, I tried it different ways, and I think it works with keeping those SDK variables as But thank you very much for the continuous and thorough help. Again, I do not think I could have figured this out without your help. Much appreciated! |
OK, indeed that code was assuming |
Note that all of this is without the RPLIDAR SDK, ie:
#define ENABLE_RPLIDAR_SDK_SUPPORT
commented out inhardwarex.h
I am not sure if this is an issue with the RPLIDAR SDK (will investigate further).
For the A3 RPLIDAR either of these will cause a change in spin rate:
motorPWM
value to the config file,RPLIDAR0.txt
SetMotorPWMRequestRPLIDAR()
endpoint#define DEFAULT_MOTOR_PWM_RPLIDAR <VALUE>
However, with the S3 none of these will cause a change of spin rate.
A slight difference between the A3 and the S1 is the connector to the little USB adapter.
The differences are shown in the attached images. There seems to be no wire to the PWM connector. I am not sure if that is the fundamental issue here.
The text was updated successfully, but these errors were encountered: