|
@@ -29,6 +29,12 @@
|
|
|
typedef std::chrono::duration<int, std::ratio<1, 1000>> milli_type;
|
|
|
|
|
|
std::atomic<bool> g_measure_cmd, g_measure_completed;
|
|
|
+// 范围:
|
|
|
+// x -2400 0
|
|
|
+// b -20 20
|
|
|
+// plc(0,0)->laser(4.315, 84.46)
|
|
|
+// x 0 2400
|
|
|
+// ->laser(1.915, 84.46)
|
|
|
|
|
|
class Temp_plc
|
|
|
{
|
|
@@ -98,6 +104,16 @@ public:
|
|
|
return m_data[CURRB_];
|
|
|
}
|
|
|
|
|
|
+ short get_last_x()
|
|
|
+ {
|
|
|
+ return m_last_data[CURRX_];
|
|
|
+ }
|
|
|
+
|
|
|
+ short get_last_b()
|
|
|
+ {
|
|
|
+ return m_last_data[CURRB_];
|
|
|
+ }
|
|
|
+
|
|
|
bool get_data(short *data)
|
|
|
{
|
|
|
if(mb_exit || ! mb_ready)
|
|
@@ -149,6 +165,7 @@ private:
|
|
|
{
|
|
|
std::lock_guard<std::mutex> lck(p->m_mutex);
|
|
|
p->mb_ready = p->m_plc.ReadShorts(DB, 0, BLOCK_SIZE, p->m_data);
|
|
|
+ memcpy(p->m_last_data, p->m_data, BLOCK_SIZE * sizeof(short));
|
|
|
}
|
|
|
p->disp_data();
|
|
|
// 查询状态
|
|
@@ -161,7 +178,12 @@ private:
|
|
|
// 等待测量结束
|
|
|
while (!g_measure_completed)
|
|
|
{
|
|
|
- usleep(1000 * 200);
|
|
|
+ usleep(1000 * 100);
|
|
|
+ {
|
|
|
+ std::lock_guard<std::mutex> lck(p->m_mutex);
|
|
|
+ p->mb_ready = p->m_plc.ReadShorts(DB, 0, BLOCK_SIZE, p->m_data);
|
|
|
+ memcpy(p->m_last_data, p->m_data, BLOCK_SIZE * sizeof(short));
|
|
|
+ }
|
|
|
std::cout << "wating for measurement." << std::endl;
|
|
|
}
|
|
|
g_measure_completed = false;
|
|
@@ -169,7 +191,14 @@ private:
|
|
|
|
|
|
// 写指令
|
|
|
p->mb_device_responsing = true;
|
|
|
- p->mb_ready = p->write_cmd(rnd.uniform(1, 100), rnd.uniform(1, 30));
|
|
|
+ short rndx, rndb;
|
|
|
+ do{
|
|
|
+ rndx = rnd.uniform(0, 8);
|
|
|
+ rndb = 0;
|
|
|
+ // rnd.uniform(-20, 20);
|
|
|
+ } while (abs(rndx*300 - p->get_curr_x()) < 300);// || abs(rndb - p->get_curr_b()) < 3);
|
|
|
+ std::cout << "write cmd: "<< rndx*300<<", "<<rndb << std::endl;
|
|
|
+ p->mb_ready = p->write_cmd(rndx*300, rndb);
|
|
|
}
|
|
|
else{
|
|
|
std::cout << "waiting for status switch." << std::endl;
|
|
@@ -185,8 +214,6 @@ private:
|
|
|
// p->write_data(1, 3);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- memcpy(p->m_last_data, p->m_data, BLOCK_SIZE * sizeof(short));
|
|
|
}else{
|
|
|
std::lock_guard<std::mutex> lck(p->m_mutex);
|
|
|
p->m_plc.disconnect();
|
|
@@ -220,6 +247,7 @@ private:
|
|
|
short m_data[BLOCK_SIZE];
|
|
|
short m_last_data[BLOCK_SIZE];
|
|
|
bool mb_device_responsing; // 设备状态切换中
|
|
|
+
|
|
|
bool mb_device_working; // 设备工作中
|
|
|
};
|
|
|
|
|
@@ -489,6 +517,7 @@ void plc_test_only()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#include "pcl/io/pcd_io.h"
|
|
|
void accuracy_validation()
|
|
|
{
|
|
|
g_measure_cmd = false;
|
|
@@ -498,11 +527,11 @@ void accuracy_validation()
|
|
|
struct tm *tc = localtime(&tt);
|
|
|
char buf[255] = {0};
|
|
|
memset(buf, 0, 255);
|
|
|
- sprintf(buf, "./result_%d-%02d-%02d_%02d:%02d:%02d.txt", tc->tm_year + 1900,
|
|
|
- tc->tm_mon + 1, tc->tm_mday, tc->tm_hour, tc->tm_min, tc->tm_sec);
|
|
|
+ sprintf(buf, "./result_%d-%02d-%02d.txt", tc->tm_year + 1900,
|
|
|
+ tc->tm_mon + 1, tc->tm_mday);
|
|
|
|
|
|
std::ofstream out;
|
|
|
- out.open(buf, std::ios::ate);
|
|
|
+ out.open(buf, std::ios::app);
|
|
|
if(!out.is_open())
|
|
|
{
|
|
|
std::cout << "open file failed, "<< buf << std::endl;
|
|
@@ -542,55 +571,84 @@ void accuracy_validation()
|
|
|
std::cout << "init detector: "<< t_detectors.size() << std::endl;
|
|
|
|
|
|
// 初始化一个plc类用于读写
|
|
|
- Temp_plc t_plc("192.168.0.1");
|
|
|
+ Temp_plc t_plc("192.168.0.100");
|
|
|
short t_plc_data[BLOCK_SIZE];
|
|
|
-
|
|
|
+ // g_measure_cmd = true;
|
|
|
char ch = 'x';
|
|
|
- while(ch != 'q')
|
|
|
+ int mcount = 0;
|
|
|
+ while (ch != 'q')
|
|
|
{
|
|
|
std::cout << "please input cmd (m for measure, q for quit):" << std::endl;
|
|
|
std::cin >> ch;
|
|
|
|
|
|
if (ch == 'm')
|
|
|
{
|
|
|
- // 获取点云
|
|
|
- pcl::PointCloud<pcl::PointXYZ>::Ptr total_cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
|
|
- for (int i = 0; i < t_lidars.size(); ++i)
|
|
|
- {
|
|
|
- pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
|
|
- if (t_lidars[i]->get_cloud(cloud, std::chrono::steady_clock::now()) == SUCCESS)
|
|
|
- {
|
|
|
- total_cloud->operator+=(*cloud);
|
|
|
- }
|
|
|
- }
|
|
|
+ std::cout << "start measure process." << std::endl;
|
|
|
|
|
|
- // 从plc获取编码值
|
|
|
- detect_wheel_ceres::Detect_result t_plc_values;
|
|
|
- t_plc.get_data(t_plc_data);
|
|
|
-
|
|
|
- // 测量获得结果,测试时通常只存在一个区域测量块
|
|
|
- detect_wheel_ceres::Detect_result t_result;
|
|
|
- std::string t_info;
|
|
|
- Error_manager ec = t_detectors[0]->detect(total_cloud, t_result.cx, t_result.cy, t_result.theta,t_result.front_theta, t_result.wheel_base, t_result.width, t_info, false);
|
|
|
-
|
|
|
- // 测量结果与plc读取数据写入文件
|
|
|
- char line_buf[512];
|
|
|
- memset(line_buf, 0, 512);
|
|
|
- if(ec == SUCCESS)
|
|
|
+ while (true)
|
|
|
{
|
|
|
- sprintf(line_buf, "success,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,plc,%.3f,%.3f,%.3f\n",
|
|
|
- t_result.cx, t_result.cy, t_result.theta,t_result.front_theta, t_result.wheel_base, t_result.width,
|
|
|
- t_plc_values.cx, t_plc_values.cy, t_plc_values.theta);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- sprintf(line_buf, "failed,0.0,0.0,0.0,0.0,0.0,0.0,plc,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n",
|
|
|
- t_plc_values.cx, t_plc_values.cy, t_plc_values.theta);
|
|
|
- std::cout << "detect failed" << std::endl;
|
|
|
+ if(g_measure_cmd){
|
|
|
+ mcount++;
|
|
|
+ g_measure_cmd = false;
|
|
|
+
|
|
|
+ int repeated_count = 6;
|
|
|
+ while(repeated_count-->0){
|
|
|
+ // 获取点云
|
|
|
+ pcl::PointCloud<pcl::PointXYZ>::Ptr total_cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
|
|
+ for (int i = 0; i < t_lidars.size(); ++i)
|
|
|
+ {
|
|
|
+ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
|
|
+ if (t_lidars[i]->get_cloud(cloud, std::chrono::steady_clock::now()) == SUCCESS)
|
|
|
+ {
|
|
|
+ total_cloud->operator+=(*cloud);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ std::cout << "get cloud size: "
|
|
|
+ << total_cloud->size() << std::endl;
|
|
|
+ // pcl::PCDWriter t_writer;
|
|
|
+ // t_writer.write(std::string("./cloud/")+std::to_string(mcount)+std::to_string(repeated_count) + ".pcd", *total_cloud);
|
|
|
+
|
|
|
+ // 测量获得结果,测试时通常只存在一个区域测量块
|
|
|
+ detect_wheel_ceres::Detect_result t_result;
|
|
|
+ std::string t_info;
|
|
|
+ Error_manager ec = t_detectors[0]->detect(total_cloud, t_result.cx, t_result.cy, t_result.theta, t_result.front_theta, t_result.wheel_base, t_result.width, t_info, false);
|
|
|
+ // Error_manager ec = t_detectors[0]->find_circle(total_cloud, t_result.cx, t_result.cy);
|
|
|
+
|
|
|
+ // 从plc获取编码值
|
|
|
+ short cx, cy, theta;
|
|
|
+ cx = t_plc.get_last_x();
|
|
|
+ cy = 0;
|
|
|
+ theta = t_plc.get_last_b();
|
|
|
+
|
|
|
+ // 测量结果与plc读取数据写入文件
|
|
|
+ char line_buf[512];
|
|
|
+ memset(line_buf, 0, 512);
|
|
|
+ if (ec == SUCCESS)
|
|
|
+ {
|
|
|
+ sprintf(line_buf, "success,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,plc,%d,%d,%d",
|
|
|
+ t_result.cx, t_result.cy, t_result.theta, t_result.front_theta, t_result.wheel_base, t_result.width,
|
|
|
+ cx, cy, theta);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ sprintf(line_buf, "failed,0.0,0.0,0.0,0.0,0.0,0.0,plc,%d,%d,%d",
|
|
|
+ cx, cy, theta);
|
|
|
+ std::cout << "detect failed: "<< ec.to_string()<<" "<<t_info.c_str() << std::endl;
|
|
|
+ }
|
|
|
+ out << line_buf << std::endl;
|
|
|
+ std::cout << line_buf << ", " << strlen(line_buf) << std::endl;
|
|
|
+ }
|
|
|
+ out << "seperation line" << std::endl;
|
|
|
+ g_measure_completed = true;
|
|
|
+ usleep(1000 * 50);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+ if(out.is_open())
|
|
|
+ {
|
|
|
+ out.close();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
@@ -605,11 +663,23 @@ int main(int argc, char *argv[])
|
|
|
// lidar_test();
|
|
|
// usleep(1000 * 1000);
|
|
|
|
|
|
+ // std::chrono::steady_clock::time_point current_time = std::chrono::steady_clock::now();
|
|
|
+ // std::chrono::time_point<std::chrono::steady_clock, milli_type> current_time_in_milliseconds = std::chrono::time_point_cast<milli_type>(current_time);
|
|
|
+ // int now_in_milliseconds = current_time_in_milliseconds.time_since_epoch().count();
|
|
|
+ // uint64 seed = uint64(now_in_milliseconds);
|
|
|
+ // cv::RNG rnd = cv::RNG(seed);
|
|
|
+ // for (size_t i = 0; i < 100; i++)
|
|
|
+ // {
|
|
|
+ // short ttx = (short)rnd.uniform(-2400, 0);
|
|
|
+ // std::cout << ttx<< std::endl;
|
|
|
+ // }
|
|
|
|
|
|
// wj test
|
|
|
// sample_detect("/home/youchen/Documents/measure/MainStructure/wj_data_records");
|
|
|
- plc_test_only();
|
|
|
- // accuracy_validation();
|
|
|
+ // plc_test_only();
|
|
|
+
|
|
|
+ accuracy_validation();
|
|
|
+
|
|
|
|
|
|
// LOG(INFO) << "end";
|
|
|
getchar();
|