学习cartographer过程中编程知识的记录

1.gflags--命令行参数解析工具

* DEFINE_bool在gflags.h中定义

* gflags主要支持的参数类型包括bool, int32, int64, uint64, double, string等

* 定义参数通过DEFINE_type宏实现, 该宏的三个参数含义分别为命令行参数名, 参数默认值, 以及参数的帮助信息

* 当参数被定义后, 通过FLAGS_name就可访问到对应的参数

//定义
DEFINE_string(configuration_directory, "",
              "First directory in which configuration files are searched, "
              "second is always the Cartographer installation to allow "
              "including files from there.");
//调用
 CHECK(!FLAGS_configuration_directory.empty())
      << "-configuration_directory is missing.";

2.CHECK

*glog里提供的CHECK系列的宏, 检测某个表达式是否为真

* 检测expression如果不为真, 则打印后面的description和栈上的信息

* 然后退出程序, 出错后的处理过程和FATAL比较像.

代码见上图,!FLAGS_configuration_directory.empty()==1,则程序继续运行,否则输出-configuration_directory is missing.并退出程序。

3.emplace

*map::emplace() 用于通过在容器中插入新元素来扩展map容器

   元素是直接构建的(既不复制也不移动).仅当键不存在时才进行插入

*std::forward_as_tuple tuple的完美转发

   该 tuple 在以右值为参数时拥有右值引用数据成员, 否则拥有左值引用数据成员

* std::piecewise_construct 分次生成tuple的标志常量

   在map::emplace()中使用forward_as_tuple时必须要加piecewise_construct,不加就报错

std::map<int, ::cartographer::mapping::PoseExtrapolator> extrapolators_;


extrapolators_.emplace(
      std::piecewise_construct, 
      std::forward_as_tuple(trajectory_id),
      std::forward_as_tuple(
          ::cartographer::common::FromSeconds(kExtrapolationEstimationTimeSec),
          gravity_time_constant));
}

4.=delete

=delete: 禁止编译器自动生成默认函数; =default: 要求编译器生成一个默认函数

* 禁止编译器自动生成 默认拷贝构造函数(复制构造函数)

Node(const Node&) = delete;

* 禁止编译器自动生成 默认赋值函数

Node& operator=(const Node&) = delete;

5.函数指针

// 一般函数指针
void Fun(int a,int b){
    int sum = a+b;
}
int main(){
    void (*FP)(int ,int);// 声明函数指针
    FP = Fun; // 赋值
    //FP = &Fun; // 赋值
    FP(1, 2);  // 调用
    //(*FP)(1, 2);// 调用
    return 0;
}

// 类内成员函数函数指针
class MyClass{
public:
    int Fun(int a, int b){// code};
};
int main(){
    MyClass* obj = new MyClass;
    int (*MyClass::pFun)(int, int) = &MyClass::Fun; // 成员函数指针声明和初始化
    (obj->*pFun)(); // 通过对象来调用成员函数指针
    delete obj;
    return 0;
}

6.lambda函数

匿名函数

[ ](int x){return x % 3 == 0;}
// 形式上用[]取代了函数名,返回值类型可以在其中声明,但是一般不写。
// []有按值传递和引用传递两种,分别是[=]和[&]
// [count 1] 按值传递
// [&count 1] 引用传递;[&] 使用所有的变量

7.ros中获取topic的名字

  // 使用ros的master的api进行topic名字的获取
  ::ros::master::V_TopicInfo ros_topics;
  ::ros::master::getTopics(ros_topics);

8.count()

if (published_topics.count(resolved_topic) == 0)

查询resolved_topic在publiced_topics中的个数

9.static_cast和dynamic_cast

c++11: static_cast关键字(编译时类型检查): static_cast < type-id > ( expression )

该运算符把expression转换为type-id类型, 但没有运行时类型检查来保证转换的安全性

(1)用于基本数据类型之间的转换, 如把int转换为char, 把int转换成enum,

(2)把空指针转换成目标类型的空指针

(3)把任何类型的表达式类型转换成void类型

(4)用于类层次结构中父类和子类之间指针和引用的转换.

c++11: dynamic_cast关键字(运行时类型检查): dynamic_cast < type-id > ( expression )

该运算符把 expression 转换成 type-id 类型的对象. Type-id必须是类的指针、类的引用或者void *

如果type-id是类指针类型, 那么expression也必须是一个指针

如果type-id是一个引用, 那么expression也必须是一个引用

dynamic_cast主要用于类层次间的上行转换(子类到父类)和下行转换(父类到子类), 还可以用于类之间的交叉转换.

在类层次间进行上行转换时, dynamic_cast和static_cast的效果是一样的;

在进行下行转换时, dynamic_cast具有类型检查的功能, 比static_cast更安全.

10.std::lower_bound()

c++11: std::lower_bound() 是在区间内找到第一个大于等于 value 的值的位置并返回, 如果没找到就返回 end() 位置,第四个参数是比较规则。

auto it = std::lower_bound(
      imu_data_.begin(), imu_data_.end(), imu_tracker->time(),
      [](const sensor::ImuData& imu_data, const common::Time& time) {
        return imu_data.time < time;
      });

11.插值

TimestampedTransform Interpolate(const TimestampedTransform& start,
                                 const TimestampedTransform& end,
                                 const common::Time time) {
  CHECK_LE(start.time, time);
  CHECK_GE(end.time, time);

  const double duration = common::ToSeconds(end.time - start.time);
  const double factor = common::ToSeconds(time - start.time) / duration;
  const Eigen::Vector3d origin =
      start.transform.translation() +
      (end.transform.translation() - start.transform.translation()) * factor;
  const Eigen::Quaterniond rotation =
      Eigen::Quaterniond(start.transform.rotation())
          .slerp(factor, Eigen::Quaterniond(end.transform.rotation()));
  return TimestampedTransform{time, transform::Rigid3d(origin, rotation)};
}

调用

return transform::Interpolate(
             transform::TimestampedTransform{std::prev(it)->data.time(),
                                             std::prev(it)->data.global_pose},
             transform::TimestampedTransform{it->data.time(),
                                             it->data.global_pose},
             time)
      .transform;

tips:transform::TimestampedTransform结构体里面包含time和transform两个变量。

12.c++智能指针中的reset成员函数

若p为智能指针对象(如:shared_ptr< int> p)
成员函数reset使用: 

p.reset(q) //q为智能指针要指向的新对象

会令智能指针p中存放指针q,即p指向q的空间,而且会释放原来的空间。(默认是delete)

p.reset(); //释放p中内置的指针指向的空间
p.reset(q.d); //将p中内置指针换为q,并且用d来释放p之前所指的空间

13.GUARDED_BY

 GUARDED_BY //声明数据成员受给定功能保护。对数据的读取操作需要共享访问,而写入操作需要独占访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值