Cell View Identifier(单元视图标识符):定义了一个独立的、完整的设计模块本身。它是“蓝图”或“模板”的ID。Instance Master Identifier(实例母体标识符):定义了一个被引用的、具体的母体对象。它是“根据蓝图制造出来的那个具体零件”的ID。myLib / inverter / schematic,又例如:myLib / inverter / layout这指的是在一个设计中被实例化(引用)的那个目标对象的身份。
当你在一个上层设计(比如 top_level 的版图)中,放置一个子单元(比如 inverter)时,你创建的是一个 “实例”。这个实例本身并不是一个独立的文件,它只是一个指针,指向它所代表的那个底层单元。
这个指针所指向的目标,就是 Instance Master。
它的标识符和 Cell View Identifier 是完全一样的! 也是 Library/Cell/View。
例如:
在你的顶层版图 myLib/top_level/layout 中,你放置了一个反相器。这个反相器实例所指向的 Master 就是 myLib/inverter/layout。
它的作用是:
告诉工具:“我这个实例,是依据哪个蓝
ctrl+alt+s截图后, 可以固定在屏幕上;alt+Actrl+insert或ctrl+shift+C;shift+insert或ctrl+shift+V;vncviewer中去, 需要打开vncconfig才行, 关闭掉vncconfig就不行(难道是bug?), vncconfig路径在/usr/bin下面(可以输入vnc然后tab查看)。vncconfig &, 使其脱离终端后台运行并最小化弹出来的vncconfig设置框, 然后就可以粘贴外部clipboard上的内容了。Always open in browser windows.Create a backup copy of files before savingfind . -name "file.txt"find ./dbcmd -type f -name "*libo.tar.gz" > a.logfind ./dbcmd -type f -name "*libo.tar.gz" | wc -lfind . -type f -name "*某个源文件多次包含同一个头文件时,如果头文件中有定义语句,那么不管是什么东西的定义,都可能会产生重定义错误。这种情况是很常见的问题,通常可以使用宏定义保护避免:
#ifndef A_H#define A_H/* 这里写真正的头文件 */#endif
使用#program once也可以,二者区别参考#program once 和 #ifndef。
但是多个源文件包含同一个头文件,宏定义或者#program once也无法进行避免了,一个本人真实遇到的例子是:。
在m_settings.h中:
#ifndef _M_SETTINGS_H#define _M_SETTINGS_H...namespace setting_ns {int aa = 10;QStringList splitArgs(const QString &s, int idx){// splitArgs函数的定义}// 这里因为aa和splitArgs的定义在头文件内,要么改成const和inline,要么将定义放到.cpp中以避免可能的重定义报错}#endif
在qsetting_obj.h中,包含了m_settings.h:
···#include "header/m_settings.h"
很不幸,在main.cpp中,我又同时include包含了qsetting_obj.h和m_settings.h,导致变量aa和splitArgs的multiple definition of重定义报错,哪怕这里套上命名空间都没用,因为是重复包含导致的和自身重复,而不是和外部的别的符号重复。
按道理来说,使用 #ifdef 等条件编译语句避免头文件在同环境被重复包含,由于#ifndef ...宏定义的保护,只会include一次m_settings.h。
但是, 请注意"同环境"这个限定,include虽然只是是简单的将文件复制进cpp吗,当多个cpp源文件包含了同一个头文件时,如果头文件中有某个局部变量或者非内联(inline)函
常见点云存储方式有pcd、ply、txt、bin文件等。kitti数据集的点云是bin格式的,而pcl的数据格式为pcd格式。在使用点云库进行开发时,一般需要将bin格式的点云数据转为pcd格式。网上有很多介绍点云格式如何转换的博客,但是很多的bin2pcd函数的写法都存在小问题,这里记录下我发现的问题并给出解决办法。
首先介绍下比较PCL中常见的PointXYZI点类型。
PointXYZI是一个简单的XYZ坐标加intensity的point类型,理想情况下,这4个变量将新建单独一个结构体,并且满足存储对齐,然而由于PCL的大部分操作会把data[4]元素设置成0或1(用于变换),不能让intensity与XYZ在同一个结构体中。因为如果这样的话其内容将会被覆盖。
例如两个点的点积会把他们的第4个元素设置成0, 否则该点积没有意义,等等。因此,对于兼容存储对齐用3个额外的浮点数来填补intensity,这样在存储方面效率较低但是符合存储对齐要求,运行效率较高。
PointXYZI结构体源代码如下:
// PointXYZI占32个字节,8个浮点数的空间,但是只有四个有效,其余的为填充struct PointXYZI {union {float data[4];struct {float x;float y;float z;}}union {struct {float intensity;}float data_c[4];}}
方法一生成的pcd文件中,可以正常可视化,但是由于最后一个点存在x=0,y=0,z=0,intensity=0的情况,生成深度图时,会出现崩溃问题。
对于使用ascll编码的pcd文件是可以用记事本打开的, 我们打开导致崩溃的pcd文件,可以发现最后一个点是0 0 0 0,这将导致创建深度图时
int a= 4; //a是左值,4 作为普通字面量是右值
1 class A {2 xxx;3 };4 A a;5 auto c = std::move(a); // std::move(a)是将亡值6 auto d = static_cast<A&&>(a); // static_cast<A&&>(a)是将亡值
左值引用就是对左值进行引用的类型,右值引用就是对右值进行引用的类型。都是别名,必须立即初始化。
type &name = exp; // 左值引用type &&name = exp; // 右值引用
std::move函数强制把左值转换为右值。
int a = 4;int &&b = a; // error, a是左值int &&c = std::move(a); // ok
反射,即Reflection,是很多高级编程语言的一种十分强大的特性,比如Java,可以于运行时加载、探知、使用编译期间完全未知的classes。而C++是天然不支持反射的,但是可以通过一些特殊手段实现类似反射的效果,本文对使用字符串创建对象,稍作探讨。
我们要实现的目标是要通过字符串创建对象,即下面的代码:
ClassT* obj = FactoryCreate("ClassT");
但是我们要知道,这并不是完全意义上的反射,因为不能取到对象的属性和值,所以只是伪反射。
//// Created by libo on 2022/11/30.//#include <map>#include <string>#include <iostream>#define REGISTER(className) \className* objectCreator##className(){ \return new (className); \} \RegisterAction g_creatorRegister##className( \#className, (constrFuncPtr)objectCreator##c
CMake工具,只需要开发者提供头文件路径、库路径、编译参数等基本参数,就能快速生成Makefile和vcproj文件等,可以做到再改动很小的情况下,满足跨平台项目的快速构建要求。由于CMake的简洁易用特性,我们通常会基于CMake构建工程,并引入第三方库进行开发工作。本文主要记录和学习CMake是如何引入第三方库的。cmake配置文件CMakeLists.txt。 CMakeLists.txt放在项目顶层目录,根据需要也可在子目录放置。CMakeLists.txt文件所在目录创建一个build文件夹,然后cd进入目录。 build目录名词也是可以自定义的。cmake .. 生成makefile。make和make install进行编译和安装。 make install需要CMakeLists.txt中定义了install的相关规则、路径、文件等才行。windows下,如果使用mingw的话编译工具为mingw32-make.exe,install安装则为mingw32-make.exe install,如果使用msvc的话编译工具为MSBuild.exe,命令MSBuild.exe XXX.vcxproj)CMakeList.txt文件需要的cmake最低版本,例如: cmake_minimum_required(VERSION 3.5)project(calculator),project(MultipleObjectTracking LANGUAGES CXX CUDA)project会影响PROJECT_SOURCE_DIR(第一个project所在的CMakelist.txt所在的文件的目录)的值。ToolChain.cmake,然后可以用includ安装CLion和CMake,其中CMake version大于2.8.3,PCL中用到了高版本的一些宏定义,低版本不兼容。
首先下载PCL-1.12.1-AllInOne-msvc2019-win64.exe 和 pcl-1.12.1-pdb-msvc2019-win64.zip,(参考2.7出现的bug,这里建议可以不要使用该版本,否则需要打开AVX开关)
%PCL_ROOT%\3rdParty\FLANN\bin%PCL_ROOT%\3rdParty\VTK\bin%OPENNI2_REDIST64%%OPENNI2_LIB64%%OPENNI2_INCLUDE64%
cmake_minimum_required(VERSION 3.23)project(pclRegister)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")set(PCL_ROOT "E:\\PCL 1.12.1") # 不要用中文的引号find_package(PCL 1.12 REQUIRED)
由于CLion基于CMake构建项目,需要重新编译OpenCV源码。
网上很多人编译过程会出现很多错误,我这里使用"科学上网",全程很顺利,建议科学上网!
安装mingw,下载支持C++11多线程的posix版本,参考文末链接。
安装完后,设置CLion的工具链。
安装CMake,需要安装cmake.gui
mingw32-make -j4
mingw32-make install
{opencv_homedir}/opencv/MinGW-build/install/x64/mingw/bin加入环境变量中的path中。
#include <iostream>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>using namespace std;using namespace cv;int main() {cv::Mat img = imread("C:\\Users\\lenovo\\Pictures\\Saved Pictures\\20170329112146_5CR4n.jpeg");if (img.empty()) {