0%

近来由于项目需要,接触了一下一直没去了解过的Python异步语法,发现和之前我熟悉的C#有很多不同。在深入Python的异步逻辑之后,由于Python在语法上保留了很多语言机制的细节(比如成员函数的self参数),我反而对C#的异步有了更深的了解。这里就来重新梳理一下各种并行方法的区别,以及他们在C#和Python上实现的区别。(这里只讨论单机的并行机制。)

总的来说,并行机制主要有进程(Process)、线程(Thread)和协程(Coroutine),其并行实现的开销依次递减,但是他们对每个任务的鲁棒性也是依次递减的。进程是操作系统资源分配的最小单元,线程则是能够被CPU并行处理的最小单元,而协程则是目前实现“并行”的最简单方法。一个进程中可以有多个线程,而一个线程中可以有多个协程。他们具体在特性上有以下区别

进程线程协程
独立内存堆××
独立处理器(可硬件并行)×
独立上下文×
独立栈、寄存器状态
Read more »

Cython提供了很多方法来搭建C/C++内存和Python对象间的桥梁,但是官方的教程只介绍了一些基础的方法。这篇文章就介绍一下我在各个场合学到和用到的Cython封装(多维)数组的技巧。一般而言这个桥梁会分为两部分,Python与Cython和Cython与C/C++。其中Python中的数组主要形式是listarray.arraynumpy.ndarray;Cython中的数组形式有[:,:,:]Memoryview/Buffer)和cython.view.array;C/C++的数组形式有**(指针)、vectorEigen::Vector/Matrix

本篇介绍的主要内容也来自于Cython的文档:Typed Memoryviews

Read more »

这次来介绍一下Cython中的特殊函数定义,Cython相比Python本身的特殊函数之外还增加了一些新的函数,用来满足对C特性的支持,其中有些内容还经常令人混淆。关于Python中特殊变量和特殊函数名的内容,请参考Python官方文档

def, cdefcpdef

首先最开始需要分清的便是Cython中的三种函数类型。def定义的对象(包括变量、函数、类型)都是普通的Python对象,是Python可以直接调用的,因此其参数都只能是Python类型或对象;cdef定义的对象则是C/C++层面的,可以直接用C/C++对象作为参数,因此不能被普通Python代码调用,这样减少了很多overhead因此可以提高运行效率。另外尽管cdef的函数不是Python对象,无法当作变量使用,但还是可以获取函数指针的。而cpdef则是同时兼具两方面特性,其本质是用cdef定义函数后再用def定义一个函数封装,使得在Cython中调用时可以调用高效的cdef版本,而在Python中调用的是与Python兼容的def版本。

Read more »

用Cython也用了很有一段时间了,这次就介绍一下它的最重要功能——使用Cython来封装C/C++代码。最基本的封装方法可以参见Cython文档中的相关页面:Interfacing with External C CodeUsing C++ in Cython,本文介绍主要是比较重要和常用的Cython/C++交互特性,而自定义Python拓展类(而不是封装现有C++)的一些操作可以参考官方教程

封装C++代码时,最重要的关键词就是extern,在定义函数时使用这个关键字就说明该声明是外部的,而使用cdef extern from语句就能指定声明对应的头文件。例如如果要封装函数func,对应的Cython语句是

1
2
cdef extern from "func.c":
void func(int arg)

Read more »

Python作为一门胶水语言,它与C/C++之间的兼容性(Interoperability)我认为是它相比其他动态语言脱颖而出的最大原因。Python原生支持的是与C语言的接口,Python的发行版自带有Python.h头文件,里面提供了在C中调用Python和反过来在Python中调用C的接口定义。但是C++就不一样了,虽然C++ ⇔ C ⇔ Python的通道是可行的,但是想要完整兼容C++的特性的话需要很多额外的重复代码(boilerplate)。因此相应针对Python/C++绑定的库也就应运而生了,我所了解的库主要有四个:Boost.PythonCythonpybind11SWIG。虽然网上也有不少比较三者的页面,但是我觉得都不够详细,这篇博客就介绍一下我基于使用这几个库的经验比较。

上面说到的这些库我基本都有接触过,其中用过的有pybind11和Cython,分别用在了我正在写的CGALPCL的绑定上。另外二者则是在其他库的代码中有读过(如Caffe和CGAL的官方绑定)。总的来说,Boost.Python和pybind11主要用于给现有C++代码提供Python绑定,并且不用学习新的语法;SWIG提供一个给C++代码编写多种语言绑定的框架,它本质上是一种代码生成器,基于SWIG自定义的语法;Cython则是基于Python的C/C++代码封装器,其本质也是代码生成器,但是Cython的语法是Python的超集,也就是说Python的代码可以零成本移植到Cython中。

Read more »

最近在研究ROS节点(ROS Node)的参数设置方式,由于系统比较复杂,并且会变得更加复杂,因此需要一个统一的参数设置方式。这里就比较一下四种参数获取方案的区别~

命令行/文件输入

由于ROS节点本身也只是普通的可执行程序,因此它可以正常地从启动参数中读取参数,另外也可以从配置文件中读取参数。这两种方法都是常规程序读取参数的方法。从命令行中读取参数有C++的Boost.Program_options库和Python的argparse的库,用来解析命令行参数输入,支持可选参数、重复参数、参数分组等等。而从文件输入的话,常见的设置格式有jsonyamltoml甚至ini等等。从这些文件中读取比较灵活,但是无法利用ROS框架,并且需要自行统一格式。

参数服务器

ROS中很有名的支持参数设置的结构是参数服务器,参数服务器是一个包含在master结点里的集中式字典结构,在ROS的Wiki上有介绍:中文|英文。参数服务器也可以从文件中读取参数,文件格式是yaml,读取的方式是在.launch文件中添加<rosparam>标签,并指定键值或者文件路径。

Read more »

最近我已经将KDE Neon作为主力系统之一了,Plasma桌面真的是太好用了!于是给家里的主机也装上了Neon,这篇文章就记录一下安装配置和美化的过程啦~

系统安装及Boot设置

双系统安装

安装Neon还是非常简单的,直接从官网下载系统镜像,烧进U盘正常安装即可。不过由于我选择的是与Windows双系统安装,因此需要手动分区。这里要纠正一下之前安装双系统博文中的分区方式。现在的Linux系统实际上只需要给根目录/分区就可以了,/home分区以前建议单独分区的原因是为了便于系统的更改,这样在修改系统分区之后(如重装系统)还能保留/home底下的文件,但其实现在很多系统已经能做到重装并保留/home分区了,这时对于我这小硬盘的笔记本来说反而导致空间利用不灵活。而交换分区/swap也是没有必要的,交换分区的存在类似于Windows下的虚拟内存,用硬盘的一部分来虚拟内存,避免内存不足的情况。新Linux可以利用交换文件完成类似功能,因此不必专门给/swap分区。(不过我猜专门给它分个区可能能提高性能?)。最后最关键的是不要给/boot分区了,/boot分区是为了保证boot文件区不被占满,以致无法正常启动。利用EFI方式启动的系统只需要有efi分区即可,而且多个系统可以利用同一个EFI分区。因此只需告诉安装器使用EFI分区作为启动分区,关于EFI的详细信息请看后文~

分区的时候还看到了之前的系统里有标记为msr的分区,是Windows的预留分区,好像具体没啥用。这里贴一篇考据文章

Read more »

最近由于工作需要,和终端命令行打交道的时间越来越多了,最近便查了一下美化命令行的方法,记录在此以供查阅~另外还推荐一个网站terminalsare.sexy,提供了很多与terminal美化相关的软件。

命令提示符(Prompt)美化

相信不少朋友也见过如下图所示美化过的命令提示符 powerline-shell这个效果的实现方式是通过安装名为Powerline的扩展程序。Powerline是一套可拓展的状态栏提示工具,可以给各种Terminal Emulator和Vim等工具增加状态栏的提示,并且十分好用~

Powerline有很多版本,有直接通过shell配置脚本实现的,也有通过独立程序进行显示的(如下列所示)。我选择的是原版powerline,安装方便,适用软件多,并且可以自行扩展。 - powerline: 这应该是最初的也是最全的powerline,基于Python - powerline-shell: 这是针对美化shell的版本,同样基于Python,配置比上面的简单 - powerline-go: 用go语言写的版本,运行更快 - bash-powerline: 用bash编写的用于bash的powerline

Read more »

在学习线性系统以及SLAM的过程中碰到了很多矩阵的求导与积分运算,但是几乎没有系统地学习过这些知识。矩阵可以构成环,因此也有很多运算性质和推广。最近大佬发给我一本《Matrix Cookbook》,非常系统地列举了进阶矩阵运算的法则,这里贴在博客上以供参考~

目录

  1. 基础内容
  2. 求导
  3. 复矩阵
  4. 求解与分解
  5. 统计与概率
  6. 多元概率分布
  7. 高斯
  8. 特殊矩阵
  9. 函数与运算符

来源

这本书可以Technical University of Denmark资料网站下到。如果链接失效了,可以直接从此处下载

由于最近工作一直在使用ROS,因此也一直在用Ubuntu。之前为了稳定性使用的是Ubuntu 16.04 LTS,而这个版本默认的桌面环境是Unity,实在是不好使,它也颇为人诟病。后来尝试了Ubuntu 18.04 LTS安装ROS Melodic,发现ROS也挺稳定的,因此18.04也用了一段时间,但是最后还是觉得不太爽,于是最终还是决定好好体验一下各种Linux选一个自己顺手的。

这篇博客里不会贴系统的截图,因为这些在网上都可以找到,而且桌面的好看与否很大程度上取决于个人的喜好和配置结果。最好的比较方法还是自己装一个系统尝试一下

至于如何尝试linux,我在Windows中使用的是Hyper-V。可以非常方便地安装各种镜像,动态分配资源,最方便的是vhdx硬盘格式可以直接mount到宿主机里。Hyper-V使用一些性能较差的Linux桌面环境时会比较卡,这个时候可以开启RemoteFX GPU(参考官方说明)。注意在Win10 1809之后,Hyper-V管理器界面不提供RemoteFX的开关了,需要用Powershell命令手动开启。

Read more »