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

前段时间MIT的新型迷你猎豹机器人火遍全网,当时我就心里痒痒要做一个,但是正在备赛RM就没做,后来看到祁乐老哥做了一个舵机4足机器人([看这里](https://space.bilibili.com/23117381/)),更是刺激了我,现在终于比赛结束了(sad :cry:),准备动手研究四足机器人。 我也打算做一个带12个舵机的四足机器人,一是这种类型的四足比较像一个四足,是我最喜欢的一种形态,二是穷,买不起好电机。 这是一系列制作过程记录,也可以把它当做教程吧,不定期更新,我也不知道什么时候能做出来,毕竟现在一穷二白,电机都买不起,还正值期末考试。 那么正式开始了,首先是腿部算法。 --- # 腿部简介 首先还是看一看机器人的腿部结构吧,这里直接借用祁乐老哥的机器人一用 ![image](https://user-images.githubusercontent.com/35989223/59141331-74b04e80-89dd-11e9-872f-d55e09af2fbd.png) 从上图可以看出,每一个腿部有三个自由度,所以对应的我们每次更新机器人姿态时都要计算出这三个舵机的角度。 首先看看两个自由度下,腿部的在平面内运动的情况。 # 腿部平面运动 可以将模型抽象如下 ![image](https://user-images.githubusercontent.com/35989223/59141409-04a2c800-89df-11e9-8fa4-35d03a3818b4.png) 我们的目标转变为根据C点坐标计算α和β角度,这里其实就是解三角函数。上图中的直线a和b就是机器人的两条腿,是可以直接测量出来的。 首先用勾股定理求出直线c的长度,然后在△ABC中运用余弦定理,可计算出∠β和∠BAC,进而求出∠α 最后求出的结果如下 ![image](https://user-images.githubusercontent.com/35989223/59141506-a0810380-89e0-11e9-8ec8-8967ead5afc1.png) 上述公式中要注意的就是坐标系的正方向的选取,也就是x和y的正负号问题。 根据上述公式就可以把二维平面的坐标转换为两个舵机的角度,进而转换为舵机的控制信号。当然要还要注意C点的取值范围,毕竟腿长是有限的。 # 腿部三维运动 现在把腿放在三维空间中看看,可以把模型简化如下 ![image](https://user-images.githubusercontent.com/35989223/59141625-4e8dad00-89e3-11e9-9d26-8068a2250134.png) 上图中黑色的两条线代表腿部的大腿和小腿两段,α、β和γ分别代表腿部三个舵机的角度位置。 面ABCD是机器人直立时腿部所在平面,即面ABCD垂直于地面。 很容易看出,腿部一定在面ABDE中,那么∠α和∠β就可以在面ABDE中,在二维平面内,用上述的方法求解出。∠γ可以在△BCD中求解出来。 最后求出的结果如下:...

Project

一切都要追溯回硬件组组长建议我搞无线下载器的那天开始,掐指一算刚好一个月,就在今天,我终于搞定了两个ESP8266模块在不借助额外的WiFi的情况下实现相互通信,搞定这一步后做一个串口转WiFi透传模块那还不是轻轻松松。 # ESP8266简介 ESP8266这个词可以理解为ESP8266EX芯片(当然,后面也有可能出现了其他芯片,这里首推ESP8266EX)以及依赖ESP8266EX芯片开发的系列模组的简称。 ESP8266EX是由乐鑫信息科技公司(Espressif)出品的一款应用于物联网编程的WiFi芯片。从它被设计出来,就引起了物联网开发的热潮,获得了业界同行的肯定。芯片的具体相关介绍,笔者这里就不占用章节篇幅,请读者自行查看乐鑫官网详细介绍。 ESP8266系列模组是深圳安信可(Ai-thinker)公司开发的一系列基于乐鑫ESP8266EX的超低功耗的UART-WiFi模块的模组,可以方便地进行二次开发,接入云端服务,实现手机3/4G全球随时随地的控制,加速产品原型设计。 从厂商角度来看,乐鑫是ESP8266的芯片厂商,安信可是依赖ESP8266生产模组,在ESP8266芯片的基础上,完善了外围器件布局和优化天线,并提供一系列开发方案的厂家。 这款芯片的设计初衷是针对loT物联网的,它可以作为`station`连接WiFi访问其他设备,可以作为`soft access port`配置为一个WiFi热点让其他设备连接,可以作为web服务器,也可以作为客户端请求数据,什么智能家居,远程操控,它都能搞定。 最最最棒的是,它的成本非常便宜,批发价格不到10块,太值了吧! ## 特点 * 802.11 b/g/n * 内置Tensilica L106 超低功耗 32 位微型 MCU,主频支持 80 MHz 和160 MHz,支持 RTOS * 内置10...

RM
other

碎碎念:俩月没写文章了,五月初终于得以返校,然后两周狂肝毕业设计,还好最后顺利毕业。6.10答辩,6.17毕业典礼,然后就回家了。回家后这段时间一直在参加今年优必选依托WAIC大会举办的WALKER仿真挑战赛,控制WALKER机器人完成指定任务。其中一项任务如下图所示。 ![image](https://user-images.githubusercontent.com/35989223/87440769-ed43fe80-c624-11ea-8e9e-7d7424b74a3e.png) 最后拿了第四名(前三有奖金),哎,还是差一点点。 这篇文章就记录一下我在比赛期间研究的机械臂角度解算,摘录自技术报告的第二章。 --- Walker机器人为仿人型机器人,普通的工业机械臂只需6个自由度即可到达活动空间内的任何位置,而人类的手臂因各个关节有角度限制,需要新增一个大臂扭转的自由度,所以Walker机器人的仿人机械臂为7自由冗余机械臂,使用传统的D-H模型求逆解的话会得到无数个解,一般选择先给定多出来的大臂扭转关节的角度,再求解其余6个自由度。 本队采用几何法求解机械臂的关节角度,遍历了大臂扭转关节的所有角度值,分别求解出对应的其余关节的角度值,然后设计代价函数,选取与上一个状态的角度相差最小的解作为当前状态的角度解。 此处以机器人左臂为例,对机械臂的逆运动学解算过程作简要介绍。左臂的自由度分布关系如图2-1所示。 ![image](https://user-images.githubusercontent.com/35989223/87441129-50ce2c00-c625-11ea-8887-7fa3cf576063.png) 为简化分析,可以将肩部的关节①②③合并为一个球关节,将腕部的关节⑤⑥⑦合并为一个球关节,最后简化图如图2-2所示。为方便解算,我们采用位姿分离的方法分析,即任务腕关节只影响末端手掌的姿态,肩部关节和肘部关节只影响腕部的空间坐标。首先根据腕部的空间坐标求解前四个关节角度。 机械臂大臂和小臂的任一姿态可由图2-3表示。因为肘部不能外拐,所以关节④的角度一定是一个负值,如图所示,在△OAB中可由余弦定理求得∠OAB,进而可求得关节4的角度。 ![image](https://user-images.githubusercontent.com/35989223/87441179-65aabf80-c625-11ea-8baf-379da8447fe2.png) 根据B点的坐标,可以求得角α和角β。如果关节③的角度为0,那么显然机械臂OAB只会在面OCB内运动,而随着关节③角度的变化,A点可以绕直线OB作圆周运动,设面OAB与面OCB的夹角为θ。将基坐标系Oxyz依次绕x轴、y轴旋转α和β角度,得到新的坐标系Ox’y’z’,如图2-4所示。在新的坐标系中,从面x’Oy’看A点,如图2-5所示,因此可以求得A点在坐标系Ox’y’z’中的坐标,然后再根据基坐标系和新的坐标系的转换关系即可求得A点在基坐标系中的坐标,进而求得关节①和关节②的角度。 ![image](https://user-images.githubusercontent.com/35989223/87441239-79562600-c625-11ea-83a6-802238f76279.png) A点在坐标系Ox’y’z’中的坐标(xA’, yA’, zA’)与在基坐标系Oxyz中的坐标(xA, yA, zA)的转换关系如下所示。 ![image](https://user-images.githubusercontent.com/35989223/87441295-870bab80-c625-11ea-8470-1e94e2c08a22.png) 针对关节③的角度求解,将基坐标系Oxyz依次绕x轴、y轴旋转关节①和关节②的角度,得到坐标系Ox’’y’’z’’,如图2-6所示。将AB投影至Ox’’y’’面,关节③的角度即为图中γ角。 ![image](https://user-images.githubusercontent.com/35989223/87441353-97238b00-c625-11ea-9f5e-f5b5cdd8d48c.png) 在求解到前4个关节的角度之后,即可求得AB杆在基坐标系中的方位(用旋转矩阵表示),而手掌的方位是已知量,即可求得手掌相对于AB的旋转矩阵。该旋转矩阵使用腕部的三个关节的角度w1、w2、w3表示如下。 ![image](https://user-images.githubusercontent.com/35989223/87441464-b3272c80-c625-11ea-89c9-6959caa7416f.png) 从上式可以看出,在求得旋转矩阵后,可以很方便地从中提取出三个关节的角度。至此,机械臂的七个自由度的角度均确定了。 我们以一定的步长遍历了面OAB与面OCB的夹角,求得了多组逆解,将这些解与上一个状态的角度相减,使用如下的代价函数评价角度的变化程度,选取所有逆解中代价函数最小的解作为当前状态的角度值,使得手臂在移动的过程中保持平滑。 ![image](https://user-images.githubusercontent.com/35989223/87441527-c2a67580-c625-11ea-9446-749a3e7e904f.png) 上式中|joints(i)|表示第i个关节的角度差值。

Project

今年的ICRA比赛的一大亮点是新增了哨岗,使用单目相机识别场地中的机器人,提供小地图。传统的目标检测算法都是预测出能框住目标的矩形框(如下图所示),但是用在机器人定位上不太合适,误差太大。 ![image](https://user-images.githubusercontent.com/35989223/81128690-75968b00-8f74-11ea-82ab-5e5cfd12b43a.png) > 截图来自[加州伯克利大学 Robomaster](https://www.bilibili.com/video/BV1ae411p7So) 真正符合需求的是目标的6D姿态检测,比较出名的就是`SSD-6D`和`YOLO-6D`(毕竟目标检测领域就它俩最快),但其实这个快是在有给力的GPU的前提下的,我试了一下用我的破电脑的CPU跑yolo-tiny,竟然要2S一帧,人家的GPU效果是145fps,差距未免太大。 ![image](https://user-images.githubusercontent.com/35989223/81129212-3832fd00-8f76-11ea-90b2-e55c35931148.png) 上图便是6D的目标检测效果,大致思路是物体中心的栅格负责检测物体的八个角点,但其实我的需求只需要检测地面的四个角点,所以我的模型还可以简化。 另外YOLO的网络太过于庞大,它不仅要检测目标,还要目标分类,支持上千种物体,我完全用不上,我只有一个类,所以我决定自己设计网络结构。 # 网络结构 我设计的网络结构如下: ![image](https://user-images.githubusercontent.com/35989223/81130375-1e93b480-8f7a-11ea-937e-a9c31b9c69a6.png) 采用的FCN全卷积神经网络结构,因此预测的时候支持任意分辨率输入。 训练时的输入我将缩放至416*416,外加有3个颜色通道,因此输入维度为3x416x416,层与层之间我加入了一个大小为3,步长为1,paddind为1的卷积层和一个大小为2,步长为2的卷积层,实现了卷积和下采样操作,最后得到一个48x6x6的输出。 最后一层是预测层,我删去了类别,同时增加了坐标输出,因为有4个角点,所以一共需要八个输出,另外还有一个置信度,表示的是当前栅格为底面中心点的概率,所以一共是九个维度的输出。 从上面的分析可以看出,我把图像分成了6x6的小格子,每个格子负责判断自己是否是底面中心,并预测出四个角点的位置,最后选取置信度较高的格子预测出的角点位置作为最终的角点位置。 需要注意的是,最后的网络层输出需要使用sigmoid函数将其输出限制在0-1之间,因此预测出的角点坐标和真实的图像坐标之间还有一个公式换算,我设计的换算公式如下图所示: ![image](https://user-images.githubusercontent.com/35989223/81131191-e772d280-8f7c-11ea-93a0-fcc7f3b493e6.png) 其中`img_scale`是卷积后图片缩小的比例,在我这里就是**416/6**。 # 损失函数 损失函数分为两部分,首先要根据图片的标签得出哪个栅格是底盘的中心。如果栅格不是底盘的中心,那么该栅格的损失函数为置信度的平方,既需要使其置信度越低越好,如果是底盘的中心,那么该栅格的损失函数为(1-置信度)^2和四个预测角点与真实角点的距离的平方和,既要使该栅格的置信度越接近1越好,角点越接近真实值越好。 公式如下: ![image](https://user-images.githubusercontent.com/35989223/81131379-93b4b900-8f7d-11ea-8a25-2be9755abe7a.png) 这里为了让损失函数快速收敛,我在每一层网络中还加入了了BatchNorm层,使输出正则化。 # 代码实现 我使用`pytorch`来搭建网络,之前想使用百度的paddle paddle(飞浆),毕竟有免费GPU白嫖,然而捣鼓一番发现不好用,特别是自定义损失函数很不好用,又回到pytorch才发现,真香!...

AI
CV

在一些特定的应用场景中,需要把一个窗口置顶,置顶的窗口可以在其他窗口激活的情况下依然保持在最上面。 先说几个概念: **窗口**:Windows是以窗口作为主要交互界面的系统,我们把那个能拖来拖去,一般带有最大化最小化关闭按钮的大方框叫做窗口,但是其实窗口的定义可以更广泛一点,一个按钮是窗口,一个文本框也是窗口。 **父窗口**:如果一个按钮(Button)被放在一个Panel(面板)上, 那按钮的父窗口就是Pane, 同样Panel的父窗口是Form,Form就是我们平时说的窗口了。 **顶级窗口**:Form的父窗口是什么? 有人说是桌面(Desktop),也有人说没有父窗口,但是通过实验得知,它没有父窗口,没有父窗口的窗口我们叫做顶级窗口,我们平时说的窗口,都是指的顶级窗口。 **句柄**:Handle,句柄是一种特殊的指针,指向的是内存里的对象, 通俗得讲它就是一个窗口(事实上远不止窗口)的把手,你有了这个句柄就能开窗关窗,改变窗口的状态。 只要我们获得顶级窗口的句柄,改变它的状态,把"不置顶"改为"置顶",就达成目的了。 # 实现逻辑 只需要不停地找窗口的父窗口, 直到某个窗口的父窗口的句柄为0(不存在),那就找到了该窗口的顶级窗口。 有函数`GetParent()`,能取得窗口的父窗口。 取得顶级窗口的句柄后, 有函数`SetWindowPos`, 指定参数HWND, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_DRAWFRAME | SWP_NOSIZE 就能置顶一个窗口。...

Win32

今天遇到一个小需求,要将一个网页中的图片都下载下来,有一百多个图片,手动右键另存为不太现实,是时候使用脚本了。 按`F12`打开调试窗口,复制输入以下代码: ```javascript //一个对象,存储页面图片数量和下载的数量 var monitorObj = { imgTotal: 0, imgLoaded: 0 } //创建a标签,赋予图片对象相关属性,并插入body var createA = function (obj, index) { var a = document.createElement("a"); a.id = obj.id; a.target =...

web

闲着无聊学一学python爬虫,定义了一个获取页面HTML内容的函数: ```python def askURL(url): request = urllib.request.Request(url)#发送请求 try: response = urllib.request.urlopen(request)#取得响应 html= response.read()#获取网页内容 # print (html) return html except urllib.error.URLError as e: if hasattr(e,"code"): print (e.code) if hasattr(e,"reason"): print (e.reason)...

web

前段时间利用GitHub的教育优惠包褥羊毛,花了5美金搞了个谷歌服务器,主要想用来搞深度学习,打算弄一个Jupyter Notebook,这样就可以通过浏览器写代码,然后在远程服务器上运行了,哪怕训练十几天都不怕(~~反正不是我自己的电脑算~~) 褥羊毛的教程很多,百度一下就可以找到,比如这一篇:[从领取Github教育礼包到DigitalOcean购买服务器](https://www.jianshu.com/p/c5e7721d886c?tdsourcetag=s_pctim_aiomsg) # 安装Jupyter ```bash sudo apt install jupyter ``` Jupyter Notebook默认只能通过本地访问,也就是`http://localhost:8888`,通过远程访问的话会提示拒绝连接。 ![image](https://user-images.githubusercontent.com/35989223/79032379-7556da00-7bd8-11ea-8c5f-1b5476bf1dd5.png) 所以需要配置远程访问。 # 生成默认配置文件 ```bash jupyter notebook --generate-config ``` 执行之后会生成`jupyter_notebook_config.py`文件,命令行会输出文件路径。 # 生成密钥 首先安装`ipython3`(因为我的环境是python3) ```bash sudo apt install...

AI

上周末硬件组的人说想搞个无线下载器,就用ARM开源的CMSIS-DAP协议,结果就这一句话我自闭了四五天,终于在一篇非常棒的文章里找到了方法,因为写的太好了,所以这里我直接把原文翻译成中文,英文原文见:[usb_express:cmsis-dap [Geniekits]](http://wiki.geniekits.com/doku.php?id=usb_express:cmsis-dap) # 在STM32F103C8上实现CMSIS-DAP * 本工程的相关代码已经上传至[Github](https://github.com/GenieKits/CMSIS-DAP_on_STM32_with_EmBitz),你也可以从我的[下载页面](http://wiki.geniekits.com/downloads)获取到源文件。 --- 如果你想在主流的MCU上进行嵌入式开发,一般来说你需要一个JTAG来连接单片机和电脑。对于ARM的MCU来说,[J-Link](https://www.segger.com/products/debug-probes/j-link/)是一个非常有名的设备,它可以提供JTAG协议将单片机个电脑连接起来。CMSIS-DAP是一个由ARM公司发布的一款类似的设备。DAP和J-Link最主要的区别在于DAP使开源的,而J-Link是一个付费产品。另外,CMSIS-DAP是基于USB HID的,所以你不需要额外安装一个固件驱动就能使用。 CMSIS-DAP 2.0.0的源码在[CMSIS V5](https://github.com/ARM-software/CMSIS_5)的GitHub仓库里。在源码里还有两个基于[LPC-Link-II](https://www.nxp.com/design/microcontrollers-developer-resources/lpc-microcontroller-utilities/lpc-link2:OM13054)的示例。这两个示例使用的是[Keil MDK](http://www.keil.com/)的[RTE组件和USB库](http://www.keil.com/support/man/docs/uv4/uv4_ca_swcomponents.htm)。在源码中还有一个叫做`USB_CM3.lib`的库文件。正因为这些,官方提供的这个示例很不方便(即非ARM的平台就没法用)。作为一个开源的狂热粉丝,我决定以完全自由的方式实现CMSIS-DAP。 STM32F103是一款非常受欢迎,非常便宜的MCU,它有着ARM Cotex-M3的内核,由[STMicroelectronics](https://www.st.com/)设计。正巧我手里有一些叫做[Bluepill](https://satoshinm.github.io/blog/171212_stm32_blue_pill_arm_development_board_first_look_bare_metal_programming.html)的最小系统板,它上面搭载了一片小巧的STM32F103C8T6芯片,并且上面也没有多余的无用的外设组件。这块开发板的唯一不足是连接在USB D+引脚的上拉电阻是10K,但按照标准它应该是1.5K,不过它的USB依然能够正常工作,没有出什么问题。 ![image](https://user-images.githubusercontent.com/35989223/67093398-1fcee100-f1e4-11e9-95f5-dec024a62408.png) 给STM32创建一个完整的嵌入式开发环境是非常简单的。在ST的官网上,我们可以下载一些免费软件,其中最重要的是[STM32CubeMX](https://www.st.com/en/development-tools/stm32cubemx.html)。这是一个图形化配置工具,帮助用户选择单片机引脚的功能,并自动生成外设初始化代码。我配置了USB、SPI1和USART1,并选择了USB的Custom HID middleware模式。GPIOB10到GPIO15被配置为JTAG调试需要的引脚。GPIOC13用于驱动单片机上的LED灯。但是我不知道怎么在STM32CubeMX中配置[CoreDebug](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/CEGFHDBB.html)和[DWT](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/CEGJGDCJ.html),它能在软件里面配置吗? ![image](https://user-images.githubusercontent.com/35989223/67093719-d5019900-f1e4-11e9-9f24-8568092cff59.png) ST公司也开发了他们自己的JTAG调试器——[STLink](https://www.st.com/en/development-tools/st-link-v2.html)。当然它并不是必要的,你也可以使用J-Link或者其他种类的调试器。STLink的驱动和程序可以在[ST官网](https://www.st.com/en/development-tools/stsw-link004.html)上下载。在网站里还有一个基于[Eclipse开发环境](https://www.eclipse.org/)开发的[IDE](https://www.st.com/en/development-tools/truestudio.html),STM32CubeMX也被包含其中。我选择的IDE是基于[CodeBlocks](http://www.codeblocks.org/)的[Embitz](https://www.embitz.org/),IDE中的[arm_none_eabi_gcc](https://launchpad.net/gcc-arm-embedded)版本是5.4.1。在我完成我的CMSIS-DAP之前,我必须使用STLink来调试我的代码。现在我在使用新做出来的CMSIS-DAP结合[OpenOCD](http://openocd.org/)进行日常的开发。 # 从CMSIS-DAP的源码开始 CMSIS V4 和 V5 中都有CMSIS-DAP的源码,我从[Github](https://github.com/ARM-software/CMSIS_5)上下载了CMSIS_5。CMSIS-DAP的核心文件有五个,但示例其实比核心代码更重要。我将从示例V1的头文件开始分析。 *...

RM
other

> 版权声明:本文为CSDN博主「阿飞__」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/afei__/article/details/81201039 # 一、Cmake 简介 cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。 # 二、常用命令 ## 1. 指定 cmake 的最小版本 ```cmake cmake_minimum_required(VERSION 3.4.1) ``` 这行命令是可选的,我们可以不写这句话,但在有些情况下,如果 CMakeLists.txt 文件中使用了一些高版本 cmake 特有的一些命令的时候,就需要加上这样一行,提醒用户升级到该版本之后再执行 cmake。 ##...

ROS