123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- #include "Sick511FileLaser.h"
- #include <unistd.h>
- RegisterLaser(Sick511File);
- CSick511FileLaser::CSick511FileLaser(int id, Automatic::stLaserCalibParam laser_param)
- :CLaser(id, laser_param)
- ,m_start_read(false)
- {
- }
- CSick511FileLaser::~CSick511FileLaser()
- {
- if (m_stream_read.is_open())
- m_stream_read.close();
- }
- bool CSick511FileLaser::Connect()
- {
- std::string ip = m_laser_param.laser_ip();
- char file[255] = { 0 };
- sprintf(file, "%s/laser%d.data", ip.c_str(), m_id + 1);
- if (m_stream_read.is_open())
- {
- m_stream_read.close();
- }
- m_stream_read.open(file, ios::in | ios::binary);
- if (!m_stream_read.good())
- return false;
- bool ret= CLaser::Connect();
- m_statu = eLaser_ready;
- m_file = file;
- return ret;
- }
- void CSick511FileLaser::Disconnect()
- {
- if(m_stream_read.is_open())
- m_stream_read.close();
- return CLaser::Disconnect();
- }
- bool CSick511FileLaser::Start()
- {
- std::lock_guard<std::mutex> lk(m_mutex);
-
- if (!this->IsReady())
- return false;
-
- m_start_read = true;
- return CLaser::Start();
-
- }
- bool CSick511FileLaser::Stop()
- {
- std::lock_guard<std::mutex> lk(m_mutex);
- m_start_read = false;
- return true;
- }
- DATA_type CSick511FileLaser::Data2PointXYZ(CBinaryData* pData, std::vector<CPoint3D>& points)
- {
- ////拼接上次未打包数据
-
- DATA_type type = eUnknow;
- CBinaryData frame;
- if (m_last_data.Length() > 0)
- {
- if (pData)
- frame = m_last_data + (*pData);
- else
- frame = m_last_data;
- m_last_data = CBinaryData();
- }
- else if(pData)
- {
- frame = (*pData);
- }
- else
- {
- return type;
- }
- int head = FindHead(frame.Data(), frame.Length());
- int tail = FindTail(frame.Data(), frame.Length());
-
- if (tail >= 0)
- {
- if (tail < frame.Length() - 1) //包尾后还有数据
- {
- m_last_data = CBinaryData(frame + tail + 1, frame.Length() - tail - 1);
- }
- if (head >= 0 && head < tail)
- {
- ////解包
- CBinaryData data(frame + head, tail - head + 1);
- if (data == "$SLSSTP")
- type = eStop;
- else if (data == "$SLSSTA")
- type = eStart;
- else if (data == "$SCLRDY")
- type = eReady;
- else if (data == "$SHWERR")
- type = eHerror;
- else if (data == "$N")
- type = eData;
- if (type == eData)
- {
- ////解析数据
- points.clear();
- if (data.Length() <= 29)
- return type;
- ////解析
- unsigned char angle_1 = 0;
- unsigned char angle_2 = 0;
- memcpy(&angle_1, (data)+26, 1);
- memcpy(&angle_2, (data)+27, 1);
- float beta_a = float(angle_1 * 256 + angle_2)*0.01;
- float start_angle = 0.0;
- float freq = 0.0;
- std::vector<float> distance;
- if (GetData(&data, distance, freq, start_angle))
- {
- float beta = (beta_a)*DEGREES;
- float sin_beta = sin(beta);
- float cos_beta = cos(beta);
- for (int i = 0; i < distance.size(); ++i)
- {
- if (distance[i] < 0.001)
- continue;
- float alpha = (start_angle + i*freq - 90.0) * DEGREES;
- float sin_alpha = sin(alpha);
- float cos_alpha = cos(alpha);
- float x = distance[i] * sin_alpha;
- float y = distance[i] * cos_alpha * sin_beta;
- float z = distance[i] * cos_alpha * cos_beta;
- points.push_back(CPoint3D(x, y, z));
- }
- //points.push_back(CPoint3D(double(distance.size()), start_angle, freq));
- }
- }
- else if (type == eStop)
- {
- m_statu = eLaser_ready;
- }
- }
- }
- else if (head >= 0)
- {
- m_last_data = CBinaryData(frame + head, frame.Length() - head);
- }
- return type;
- }
- bool CSick511FileLaser::RecvData(CBinaryData& data)
- {
- if (m_start_read == false)
- return false;
- if (!m_stream_read.is_open())
- return false;
-
- if (m_stream_read.eof())
- {
- Stop();
- m_stream_read.close();
- usleep(100*1000);
- m_stream_read.open(m_file.c_str(), ios::in | ios::binary);
- }
- char buf[512] = { 0 };
- m_stream_read.read(buf, 512);
- int count = m_stream_read.gcount();
- if (count > 0)
- {
- CBinaryData bin_data(buf, count);
- data = bin_data;
- return true;
- }
- return false;
- }
- int CSick511FileLaser::FindHead(char* buf, int b_len)
- {
- int i = 0;
- if (b_len < 2)
- return NULL;
- for (i = 0; i <= b_len; i++)
- {
- if (b_len > 10)
- {
- if (buf[i] == '$'&& buf[i + 1] == 'N' && buf[i + 7] == 'S'
- &&buf[i + 8] == '5'&&buf[i + 9] == '1'&&buf[i + 10] == '1')
- return i;
- }
- if (b_len > 7)
- {
- if (buf[i] == '$'&& buf[i + 1] == 'S'&&buf[i + 7] == '*')
- return i;
- }
- }
- return -1;
- }
- int CSick511FileLaser::FindTail(char* buf, int b_len)
- {
- int i = 0;
- for (i = 0; i <= b_len; i++)
- {
- if (b_len >= i + 5)
- {
- if (buf[i] == '*' && buf[i + 3] == '\r'&&buf[i + 4] == '\n')
- return i + 4;
- }
- }
- return -9999999;
- }
- bool CSick511FileLaser::GetData(CBinaryData* pData, std::vector<float>& distance,
- float& freq, float& start_angle)
- {
- struct stData
- {
- const char* data;
- int length;
- };
- std::vector<struct stData> strDatas;
- int start = 0;
- int end = 0;
- int LMDscandata_index = -1;
- for (int i = 0; i < pData->Length(); ++i)
- {
- if ((*pData)[i] == ' ')
- {
- end = i;
- if (end > start)
- {
- struct stData strData;
- strData.data = (*pData + start);
- strData.length = end - start;
- strDatas.push_back(strData);
- if (strncmp(strData.data, "LMDscandata", 11) == 0)
- LMDscandata_index = strDatas.size() - 1;
- }
- end = i + 1;
- start = end;
- }
- }
- if (strDatas.size() > 26 + LMDscandata_index - 1)
- {
- struct stData start_angle_str = strDatas[23 + LMDscandata_index - 1];
- long start_angle_l = Str0x2Long(start_angle_str.data, start_angle_str.length);
- start_angle = float(start_angle_l)*0.01;
- struct stData freq_str = strDatas[24 + LMDscandata_index - 1];
- long freq_l = Str0x2Long(freq_str.data, freq_str.length);
- freq = float(freq_l)*0.0001;
- struct stData count_str = strDatas[25 + LMDscandata_index - 1];
- long count = Str0x2Long(count_str.data, count_str.length);
- if (strDatas.size() >= 26 + LMDscandata_index - 1 + count)
- {
- for (int i = 26 + LMDscandata_index - 1; i < 26 + LMDscandata_index - 1 + count; ++i)
- {
- float dis = float(Str0x2Long(strDatas[i].data, strDatas[i].length));
- distance.push_back(dis);
- }
- return true;
- }
- }
- return false;
- }
- long CSick511FileLaser::Str0x2Long(const char* data, int len)
- {
- long sum = 0;
- for (int i = 0; i < len; ++i)
- {
- char c = data[i];
- int n = 0;
- if (c >= 48 && c <= 57)
- n = c - 48;
- else if (c >= 65 && c <= 70)
- n = c - 65 + 10;
- sum += n*pow(16, len - i - 1);
- }
- return sum;
- }
|