123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- //
- // Created by zx on 23-9-20.
- //
- #include "WheelFactor.h"
- #include <pcl/io/pcd_io.h>
- WheelsPredictor::WheelsPredictor() {
- valid_ = false;
- length_ = 0;
- wheelBase_ = 0;
- width_ = 0;
- diff_ = 0;
- }
- WheelsPredictor::~WheelsPredictor() = default;
- void WheelsPredictor::reset() {
- valid_ = false;
- }
- bool WheelsPredictor::update(pcl::PointCloud<pcl::PointXYZ>::Ptr src, double cx, double cy, double theta,
- double width, double wheelbase) {
- if (src->empty()) {
- LOG(WARNING) << "cloud is empty,cloud size:" + std::to_string(src->size());
- return false;
- }
- LOG(INFO) << "input params -----> cx: " << cx << ", cy: " << cy << ", theta: "
- << theta << ", width: " << width << ", wheelbase: " << wheelbase;
- pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
- pcl::copyPointCloud(*src, *cloud);
- //绕原点摆正
- float minx = 1e8, maxx = -1e8, miny = 1e8, maxy = -1e8;
- float t_minx = 1e8, t_maxx = -1e8;
- for (auto &point: cloud->points) {
- pcl::PointXYZ pt(point);
- t_minx = MIN(t_minx, point.x);
- t_maxx = MAX(t_maxx, point.x);
- point.x = pt.x * cos(-theta) - pt.y * sin(-theta);
- point.y = pt.x * sin(-theta) + pt.y * cos(-theta);
- minx = MIN(minx, point.x);
- maxx = MAX(maxx, point.x);
- miny = MIN(miny, point.y);
- maxy = MAX(maxy, point.y);
- }
- float car_y = (miny + maxy) / 2.f;
- LOG(INFO) << "befor trans -----> t_minx: " << t_minx << ", t_maxx: " << t_maxx;
- LOG(INFO) << "minx: " << minx << ", maxx: " << maxx << ", miny: " << miny << ", maxy: " << maxy;
- minx = 1e8, maxx = -1e8;
- for (auto &point:cloud->points) {
- if (point.y < car_y - 0.5 || point.y > car_y + 0.5) {
- continue;
- }
- minx = MIN(minx, point.x);
- maxx = MAX(maxx, point.x);
- }
- float car_x = (minx + maxx) / 2.;
- LOG(INFO) << "after only use body-----> minx: " << minx << ", maxx: " << maxx;
- length_ = maxy - miny;
- float x = cx * cos(-theta) - cy * sin(-theta);
- float y = cx * sin(-theta) + cy * cos(-theta);
- LOG(INFO) << "carx - wheel x = (" << car_x << " - " << x << ") = " << car_x - x;
- if (fabs(car_x - x) < 0.03) {
- diff_ = y - car_y;
- width_ = width;
- wheelBase_ = wheelbase;
- LOG(INFO) << "update diff: " << diff_ << ", width: " << width_ << ", wheelbase: " << wheelBase_;
- valid_ = true;
- } else {
- valid_ = false;
- }
- return valid_;
- }
- bool WheelsPredictor::predict(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, double theta, PreResult &res) {
- if (!valid_) {
- return false;
- }
- float minx = 1e8, maxx = -1e8, miny = 1e8, maxy = -1e8;
- for (int i = 0; i < cloud->size(); ++i) {
- pcl::PointXYZ pt = cloud->points[i];
- float x = pt.x * cos(-theta) - pt.y * sin(-theta);
- float y = pt.x * sin(-theta) + pt.y * cos(-theta);
- cloud->points[i].x = x;
- cloud->points[i].y = y;
- if (x < minx) minx = x;
- if (x > maxx) maxx = x;
- if (y < miny) miny = y;
- if (y > maxy) maxy = y;
- }
- float car_x = (minx + maxx) / 2.;
- float car_y = (miny + maxy) / 2.;
- minx = 1e8, maxx = -1e8;
- for (int i = 0; i < cloud->size(); ++i) {
- pcl::PointXYZ pt = cloud->points[i];
- if (pt.y < car_y + 0.5 && pt.y > car_y - 0.5) {
- if (pt.x < minx) minx = pt.x;
- if (pt.x > maxx) maxx = pt.x;
- }
- }
- car_x = (minx + maxx) / 2.;
- float length = fabs(maxy - miny);
- if (fabs(length_ - length) < 0.1) {
- float x = car_x;
- float y = car_y + diff_;
- res.x = x * cos(theta) - y * sin(theta);
- res.y = x * sin(theta) + y * cos(theta);
- res.theta = theta;
- res.w = width_;
- res.wheelBase = wheelBase_;
- res.frontTheta = 0;
- return true;
- }
- return false;
- }
|