imuncle.github.io icon indicating copy to clipboard operation
imuncle.github.io copied to clipboard

大叔的个人小站

Results 100 imuncle.github.io issues
Sort by recently updated
recently updated
newest added
trafficstars

不得不在家办公,给电脑装了个Ubuntu虚拟机跑ROS,结果在编译的时候遇到了问题: ![image](https://user-images.githubusercontent.com/35989223/75855227-c252ce00-5e2c-11ea-997b-f062d6278ece.png) 原因是没有足够的运行内存给编译程序用,我参考这篇博客:[Linux虚拟机增加内存后增加swap空间](http://blog.chinaunix.net/uid-12427199-id-3474464.html),成功扩大了内存。 其实swap空间就是把硬盘上的空间用来当内存使用,是一种折中的处理方法。 ## 1. 用dd命令创建一个2G的文件(2G=1024×1024×2=2097152) ```bash sudo dd if=/dev/zero of=/var/swapfile bs=1024 count=2097152 ``` ## 2. 将它创建为Linux Swap虚拟交换文件 ```bash sudo mkswap /var/swapfile ``` ## 3. 激活并使用/var/swapfile交换文件 ```bash sudo swapon...

ROS

# 新建功能包 ```bash mkdir src cd src catkin_create_pkg learning_communication std_msgs rospy roscpp cd ../ catkin_make source devel/setup.bash ``` # 创建Publisher ```cpp // ROS节点初始化 ros::init(argc, argv, "talker"); // 创建节点句柄 ros::NodeHandle n;...

ROS

3D立体画是裸眼3D的一种,最初是由一些极具创意的画家在街道或平地上创作的,后来又有了在纸上的绘制的作品。我的第一幅3D立体画是高二上画的: ![image](https://user-images.githubusercontent.com/35989223/73521186-530a4880-4440-11ea-802d-723247c23eb6.png) 然后上大学后许久没有画过了。 近期武汉新型冠状病毒肺炎疫情严重,只能呆在家,闲来无事想写一个能直接生成3D立体画的程序。 思路很简单,我们的目的是在相机的图像中将需要显示的物体放置在纸面上,还是放出这个世界坐标和图像坐标的关系: ![image](https://user-images.githubusercontent.com/35989223/72493552-6d4b0080-385c-11ea-8081-a508eec71bb1.png) 首先定义一个相机: ```javascript // 模拟相机类 var Camera = function() { var arr = [[1000, 0, 400], [0, 1000, 300], [0, 0, 1]]; this.intrinsic = new...

web

# OLED简介 我平时最喜欢玩的是中景园的0.96寸的单色OLED,有IIC通信和SPI通信两款,上面的驱动芯片是SSD1306,用起来非常方便。 ![image](https://user-images.githubusercontent.com/35989223/67146192-44e25300-f2bb-11e9-9c64-d85bdd8d0179.png) 该OLED的分辨率是128×64,显示内容时纵坐标上都是以页(page)为单位进行操作,所以这个0.96寸的OLED纵向为8个page。若有一个图标占用了2个page,那么在这个图标2个page的上下空白部分,不能显示其它内容。因为要在这个page的空白部分显示其它内容的话,会擦除这个page上已存在的内容。 有一种方法可以实现在空白部分显示其它内容,就是用并行接口去控制点阵屏,并行接口可以读取屏RAM的显示内容。我们进行写page之前,先把page里面的数据读出来,进行或操作之后再写,这样就保留了之前的图标内容。这种方法会占用MCU很多的IO口。更关键的是,我并没有并行接口,我只有IIC或者SPI,不支持读取屏上某一点的显示内容。 # GUI 图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面。目前网上已经有很多成熟的专门针对嵌入式系统的GUI,比如emWIN,MicroWindows,MiniGui,ZLG AWTK等。 实现GUI的基础就是实现画点、画线、画圆、画矩形、填充、显示文字等操作,所以下面我就具体讲怎么实现这些基本功能。 # OLED GUI 我使用的办法是在MCU里面创建一个和屏大小相同的数组,不过因为OLED屏上每一个像素点只有两个状态,亮或不亮,所以我完全可以用一位二进制数来表示,所以我使用了128×8的数组来存储OLED的像素点数据。所有的GUI操作均是直接操作这个数组,最后再统一将这个数组传给OLED显示出来,效率也提高了不少。 ```c uint8_t OLED_GRAM[128][8]; ``` ## 操作点 直接上代码 ```c //画点 //x:0~127 //y:0~63 //t:1...

other

因为商用激光雷达频率多在10~15Hz之间,当机器人快速运动时可能会出现激光雷达数据变形的情况,这会在一定程度上影响机器人的定位和路径规划。因此对激光雷达数据的纠正很关键。 我参考了[激光雷达移动状态下的数据矫正](https://www.cnblogs.com/wenhust/p/8735390.html)这篇文章,其中基本上是一篇论文的中文翻译,论文也在这篇文章中给出了。 我根据论文中的内容使用ROS和OpenCV搭建了一个仿真环境,在这个仿真程序中,雷达数据为10Hz,里程计数据为100Hz,使用键盘控制机器人的前后左右旋转。雷达一圈采集360个点。纠正的大体思路如下: 因为激光雷达数据频率较低,但每一帧中有360个数据,所以激光雷达的每一个数据时间间隔是小于里程计的。首先我们需要构建一个队列存储最近20帧里程计数据,然后在激光雷达数据回调函数中,针对每一个数据的时间戳找到对应的里程计近似数据,最后将这些里程计位姿对齐到最后一帧里程计数据(因为原始数据中只有最后一个雷达数据是准确的。) 程序有四个文件,直接上代码,关键部分有注释: * keyboard.h ```cpp // 作者:谢胜 // 功能:读取键盘输入(无需回车),可用于模拟程序中机器人控制的输入信号 #ifndef KEYBOARD_H #define KEYBOARD_H #include #include #include #include #include #include #include class Keyboard { public: Keyboard() { kfd...

RM
ROS

源码地址:https://github.com/RoboMaster/RoboRTS/tree/ros/roborts_planning --- 该节点包含两部分:全局路径规划和局部路径规划,全局路径规划使用A*算法,局部路径规划使用TEB算法,分别在`global_planner`和`local_planner`中。 # 全局路径规划节点代码结构详解 ## 1.文件目录 ```bash global_planner ├── CMakeLists.txt ├── global_planner_algorithms.h #包含实现具体算法类的头文件 ├── global_planner_base.h #全局规划算法的抽象类 ├── global_planner_test.cpp #全局规划的测试节点 ├── global_planner_node.cpp #全局规划核心功能执行的节点和Main函数 ├── global_planner_node.h ├── a_star_planner #A*全局规划算法实现 │ ├──...

RM

源码地址:https://github.com/RoboMaster/RoboRTS/tree/ros/roborts_base --- ## 1.文件目录 ```bash roborts_base ├── CMakeLists.txt ├── cmake_module │ └── FindGlog.cmake ├── chassis #底盘模块ROS接口封装类 │ ├── chassis.cpp │ └── chassis.h ├── gimbal #云台模块ROS接口封装类 │ ├── gimbal.cpp │ └──...

RM

源码地址:https://github.com/RoboMaster/RoboRTS/tree/ros/roborts_costmap --- ## 1.文件结构 ```bash roborts_costmap ├── CMakeLists.txt ├── cmake_module │ ├── FindEigen3.cmake │ └── FindProtoBuf.cmake ├── config # 配置文件 │ ├── costmap_parameter_config_for_decision.prototxt │ ├── costmap_parameter_config_for_global_plan.prototxt │ ├── costmap_parameter_config_for_local_plan.prototxt │...

RM

这是19年12月初的小项目,当时是为了给人培训PnP算法而写的一个小示例。 这一个半月都没写博客,但我几乎每天都在写代码学东西,一直没时间总结,终于明天就要离开学校回家了,今天便有了时间稍微写写过去这一个半月的所做所学。 OpenCV实现AR本质上是将一系列世界坐标投影到图像坐标的过程,属于最基础的3D知识。这里面的东西不多,首先从相机标定开始说。 # 相机标定 目前被大家普遍使用的是张正友标定法,这里就不给出具体的算法推导了,推荐几篇将算法原理的文章: * [相机标定——张正友棋盘格标定法](https://blog.csdn.net/JennyBi/article/details/85764988) * [SLAM入门之视觉里程计(6):相机标定 张正友经典标定法详解](https://www.cnblogs.com/wangguchangqing/p/8335131.html) * [【计算机视觉】1. 张正友平面标定法](https://zhuanlan.zhihu.com/p/36371959) * [从零开始学习「张氏相机标定法」(一) 7](http://www.sohu.com/a/220313594_100007727) 总之,从不同角度拍几张棋盘图,就可以使用张正友标定法计算出相机的内参矩阵。相机最重要的坐标变换关系如下(为简单起见,这里省略了畸变矩阵): ![image](https://user-images.githubusercontent.com/35989223/72493552-6d4b0080-385c-11ea-8081-a508eec71bb1.png) 其中矩阵K就是相机的内参矩阵。在内参矩阵已知的情况下,对于一个点来说,其在世界坐标系下的坐标、在图像坐标系中的坐标、相机的外参矩阵,这三个量只要知道其中任意两个就可以求得第三个。 # 程序思路分析 我们要实现的是AR功能,举个例子,我们想将一个指定长宽高的方块放置在图像中的一个平面上,也就是说,我们给定了世界坐标,需要求解图像坐标,拿到方块八个顶点的图像坐标后,就可以相互连线绘制出方块。 根据上面的等式,我们还差相机的外参矩阵。这里就用到了PnP算法。 PnP算法的功能是根据一个平面的四个点的图像和真实世界坐标计算相机相对于该平面的姿态,即相机的外参矩阵。算法很简单,关于它的算法推导可以看这篇:[3D-2D:PnP算法原理](https://blog.csdn.net/u014709760/article/details/88029841) 所以我们的程序思路是,首先标定相机,获取相机的内参(这一步只需要拿到相机后标定一下就行,相机不变内参就不变),然后寻找我们目标平面的四个不共线的特征点,根据这四个点的世界坐标和图像坐标求解出相机的外参,然后给定要显示图像的各个点的坐标,使用上述矩阵等式求出对应的图像坐标,最后画线即可。 # 具体程序实现 ```cpp int...

RM
CV

前几天春节期间花了点时间把个人网站改造了一下,在这里做个总结Mark一下。 改造的念头来源于一次无意间翻到的一个在issue页面建立的博客(相当于只有后台的博客),我就有了要将网站与issue挂钩的想法。 之前我的网站是基于[Editor.md](https://pandao.github.io/editor.md/examples/)的,以在本地写好相应的.md文件后push到GitHub上的方式来发表文章,也不是太麻烦,唯有一个遗憾,就是没有评论功能。去年的时候我接触过[Gitment](https://github.com/imsun/gitment),但当时还不太了解GitHub,更别说issue了,而且Gitment需要手动为每个文章初始化一次,显得比较麻烦。现在作者网站的安全证书过期了,导致Gitment访问不是很稳定。 于是我决定自己来试着把GitHub的issues和comments都集成到我的网站里。 首先是注册一个GitHub的OAuth App,点[这里](https://github.com/settings/applications/new)可以注册。注册后可以拿到对应的`client_id`和`client_secret`。 最开始我一直想通过纯JavaScript实现此功能,但总是遇到各种各样的问题,最后遇到了一个实在无解的问题,详情可以点[这里](?id=21),然后我发邮件询问GitHub,结果直接来了个官方劝退: > Exchanging a code for a token is not possible from a browser via JavaScript -- it's not something that our OAuth flow...

web