好快的時間,小米都10周年了。這次10周年照例也是一次營銷,雷軍看來是愛上演講這樣的方式了,以時間軸為中心,娓娓道來其中的事情。這次重點其實說的是,自己沖擊第一的決心,大筆墨的著色了港股上市和美國的封鎖。這些大家都可以去看(我就看了他寫的演講稿,沒有看視頻)。在演講會的末尾,走出了一條“狗”,簡單的做了一些動作,沒有太敢修就又牽回去了。估計是怕小愛那樣的出丑,或者是本身就做到這里了。雷軍給它起名為鋼蛋。很多人覺得CyberDog就是鋼蛋的意思,事實上不是。

gif圖,主要看傳感器的布局

是網絡狗的意思
今天就和我研究一下這條狗的相關,怎么說呢。每家媒體都在報道,但是稿子千篇一律,連洗稿都懶的洗。我寫的話,就是又臭又長的“水文”了。
首先主控是NVIDIA JETSON XAVIER NX:
https://www.nvidia.cn/autonomous-machines/embedded-systems/jetson-xavier-nx/
就是這個樣子的一個機器,也是邊緣AI平臺里面最貴的型號
我不知道自動駕駛的平臺算嗎?估計不算
| Jetson Nano 硬件情況探查 |
| NVIDIA Jetson nano I2C連接+網線SSH直連+smaba配置 |
| NVIDIA Jetson nano安裝Jtop(資源監控) |
| NVIDIA Jetson nano安裝GPIO安裝 |
| NVIDIA Jetson nano安裝I2C屏幕(ssd1306主控).上 |
| NVIDIA Jetson nano環境配置上 |
| jetson NanoCamera(使用) |
| 解決jetson Nano中python版本問題(Ubuntu系統都適用) |
| jetson Nano安裝pycuda(編譯安裝版) |
| NVIDIA Jetson:實現一切自主的 AI 平臺.1 |
其實都是一樣的東西,我寫了幾十篇的Nano文章了,可以參考的看

板載核心
Jetson Xavier NX最多可提供21個TOPS,非常適合嵌入式和邊緣系統中的高性能計算和AI。您可以獲得384個NVIDIA CUDA? Cores,48個Tensor Cores,6個Carmel ARM CPU和兩個NVIDIA深度學習加速器(NVDLA)引擎的性能。這些功能與超過51GB / s的內存帶寬,視頻編碼和解碼相結合,使Jetson Xavier NX成為并行運行多個現代神經網絡并同時處理來自多個傳感器的高分辨率數據的首選平臺。

機器人適合在這些的地方部署
這里插一句機器狗,并不是自研,而是基于MIT Mini Cheetah和ROS 2的開源平臺。
https://github.com/search?q=MIT+Mini+Cheetah你去探索這里
https://github.com/Derek-TH-Wang/quadruped_ctrl如果你買不起狗(我買不起,說的就是我)

你可在虛擬環境內進行仿真操作

就這樣,想摸摸
https://github.com/sevocrear/Mini-Cheetah-ROS一個ROS的包
https://github.com/wei1224hf/RuFengRobot另一個庫,包含大量的資料。保證你可以生產機械狗

里面有大量的機械結構圖紙
import numpy as npimport matplotlib.pyplot as pltimport matplotlib.animation as animationfrom matplotlib.widgets import Slider, Button#plt.rcParams['animation.ffmpeg_path'] = 'D:/portableSoftware/ShareX/ShareX/Tools/ffmpeg.exe'interval = 50 # ms, time between animation framesfig, ax = plt.subplots(figsize=(6, 6))plt.subplots_adjust(left=0.15, bottom=0.35)ax.set_aspect('equal')plt.xlim(-1.4*40, 1.4*40)plt.ylim(-1.4*40, 1.4*40)# plt.grid()t = np.linspace(0, 2*np.pi, 400)delta = 1e = 2n = 10RD = 40rd = 5# plt.grid()# draw pinl0, = ax.plot([], [], 'k-', lw=2)l1, = ax.plot([], [], 'k-', lw=2)l2, = ax.plot([], [], 'k-', lw=2)l3, = ax.plot([], [], 'k-', lw=2)l4, = ax.plot([], [], 'k-', lw=2)l5, = ax.plot([], [], 'k-', lw=2)l6, = ax.plot([], [], 'k-', lw=2)l7, = ax.plot([], [], 'k-', lw=2)l8, = ax.plot([], [], 'k-', lw=2)l9, = ax.plot([], [], 'k-', lw=2)l10, = ax.plot([], [], 'k-', lw=2)l11, = ax.plot([], [], 'k-', lw=2)l12, = ax.plot([], [], 'k-', lw=2)l13, = ax.plot([], [], 'k-', lw=2)l14, = ax.plot([], [], 'k-', lw=2)l15, = ax.plot([], [], 'k-', lw=2)l16, = ax.plot([], [], 'k-', lw=2)l17, = ax.plot([], [], 'k-', lw=2)l18, = ax.plot([], [], 'k-', lw=2)l19, = ax.plot([], [], 'k-', lw=2)l20, = ax.plot([], [], 'k-', lw=2)l21, = ax.plot([], [], 'k-', lw=2)l22, = ax.plot([], [], 'k-', lw=2)l23, = ax.plot([], [], 'k-', lw=2)l24, = ax.plot([], [], 'k-', lw=2)l25, = ax.plot([], [], 'k-', lw=2)l26, = ax.plot([], [], 'k-', lw=2)l27, = ax.plot([], [], 'k-', lw=2)l28, = ax.plot([], [], 'k-', lw=2)l29, = ax.plot([], [], 'k-', lw=2)l30, = ax.plot([], [], 'k-', lw=2)l31, = ax.plot([], [], 'k-', lw=2)l32, = ax.plot([], [], 'k-', lw=2)l33, = ax.plot([], [], 'k-', lw=2)l34, = ax.plot([], [], 'k-', lw=2)l35, = ax.plot([], [], 'k-', lw=2)l36, = ax.plot([], [], 'k-', lw=2)l37, = ax.plot([], [], 'k-', lw=2)l38, = ax.plot([], [], 'k-', lw=2)l39, = ax.plot([], [], 'k-', lw=2)l40, = ax.plot([], [], 'k-', lw=2)for i in range(int(10)):x = (5*np.sin(t) + 40*np.cos(2*i*np.pi/10))y = (5*np.cos(t) + 40*np.sin(2*i*np.pi/10))if i == 0:l0, = ax.plot(x, y, 'k-')if i == 1:l1, = ax.plot(x, y, 'k-')if i == 2:l2, = ax.plot(x, y, 'k-')if i == 3:l3, = ax.plot(x, y, 'k-')if i == 4:l4, = ax.plot(x, y, 'k-')if i == 5:l5, = ax.plot(x, y, 'k-')if i == 6:l6, = ax.plot(x, y, 'k-')if i == 7:l7, = ax.plot(x, y, 'k-')if i == 8:l8, = ax.plot(x, y, 'k-')if i == 9:l9, = ax.plot(x, y, 'k-')if i == 10:l10, = ax.plot(x, y, 'k-')if i == 11:l11, = ax.plot(x, y, 'k-')if i == 12:l12, = ax.plot(x, y, 'k-')if i == 13:l13, = ax.plot(x, y, 'k-')if i == 14:l14, = ax.plot(x, y, 'k-')if i == 15:l15, = ax.plot(x, y, 'k-')if i == 16:l16, = ax.plot(x, y, 'k-')if i == 17:l17, = ax.plot(x, y, 'k-')if i == 18:l18, = ax.plot(x, y, 'k-')if i == 19:l19, = ax.plot(x, y, 'k-')if i == 20:l20, = ax.plot(x, y, 'k-')if i == 21:l21, = ax.plot(x, y, 'k-')if i == 22:l22, = ax.plot(x, y, 'k-')if i == 23:l23, = ax.plot(x, y, 'k-')if i == 24:l24, = ax.plot(x, y, 'k-')if i == 25:l25, = ax.plot(x, y, 'k-')if i == 26:l26, = ax.plot(x, y, 'k-')if i == 27:l27, = ax.plot(x, y, 'k-')if i == 28:l28, = ax.plot(x, y, 'k-')if i == 29:l29, = ax.plot(x, y, 'k-')if i == 30:l30, = ax.plot(x, y, 'k-')if i == 31:l31, = ax.plot(x, y, 'k-')if i == 32:l32, = ax.plot(x, y, 'k-')if i == 33:l33, = ax.plot(x, y, 'k-')if i == 34:l34, = ax.plot(x, y, 'k-')if i == 35:l35, = ax.plot(x, y, 'k-')if i == 36:l36, = ax.plot(x, y, 'k-')if i == 37:l37, = ax.plot(x, y, 'k-')if i == 38:l38, = ax.plot(x, y, 'k-')if i == 39:l39, = ax.plot(x, y, 'k-')if i == 40:l40, = ax.plot(x, y, 'k-')def draw_pin_init():l0.set_data([0], [0])l1.set_data([0], [0])l2.set_data([0], [0])l3.set_data([0], [0])l4.set_data([0], [0])l5.set_data([0], [0])l6.set_data([0], [0])l7.set_data([0], [0])l8.set_data([0], [0])l9.set_data([0], [0])l10.set_data([0], [0])l11.set_data([0], [0])l12.set_data([0], [0])l13.set_data([0], [0])l14.set_data([0], [0])l15.set_data([0], [0])l16.set_data([0], [0])l17.set_data([0], [0])l18.set_data([0], [0])l19.set_data([0], [0])l20.set_data([0], [0])l21.set_data([0], [0])l22.set_data([0], [0])l23.set_data([0], [0])l24.set_data([0], [0])l25.set_data([0], [0])l26.set_data([0], [0])l27.set_data([0], [0])l28.set_data([0], [0])l29.set_data([0], [0])l30.set_data([0], [0])l31.set_data([0], [0])l32.set_data([0], [0])l33.set_data([0], [0])l34.set_data([0], [0])l35.set_data([0], [0])l36.set_data([0], [0])l37.set_data([0], [0])l38.set_data([0], [0])l39.set_data([0], [0])l40.set_data([0], [0])def draw_inner_pin_init():p0.set_data([0], [0])p1.set_data([0], [0])p2.set_data([0], [0])p3.set_data([0], [0])p4.set_data([0], [0])p5.set_data([0], [0])p6.set_data([0], [0])p7.set_data([0], [0])p8.set_data([0], [0])p9.set_data([0], [0])def pin_update(n, d, D):for i in range(int(n)):x = (d/2*np.sin(t) + D/2*np.cos(2*i*np.pi/n))y = (d/2*np.cos(t) + D/2*np.sin(2*i*np.pi/n))if i == 0:l0.set_data(x, y)if i == 1:l1.set_data(x, y)if i == 2:l2.set_data(x, y)if i == 3:l3.set_data(x, y)if i == 4:l4.set_data(x, y)if i == 5:l5.set_data(x, y)if i == 6:l6.set_data(x, y)if i == 7:l7.set_data(x, y)if i == 8:l8.set_data(x, y)if i == 9:l9.set_data(x, y)if i == 10:l10.set_data(x, y)if i == 11:l11.set_data(x, y)if i == 12:l12.set_data(x, y)if i == 13:l13.set_data(x, y)if i == 14:l14.set_data(x, y)if i == 15:l15.set_data(x, y)if i == 16:l16.set_data(x, y)if i == 17:l17.set_data(x, y)if i == 18:l18.set_data(x, y)if i == 19:l19.set_data(x, y)if i == 20:l20.set_data(x, y)if i == 21:l21.set_data(x, y)if i == 22:l22.set_data(x, y)if i == 23:l23.set_data(x, y)if i == 24:l24.set_data(x, y)if i == 25:l25.set_data(x, y)if i == 26:l26.set_data(x, y)if i == 27:l27.set_data(x, y)if i == 28:l28.set_data(x, y)if i == 29:l29.set_data(x, y)if i == 30:l30.set_data(x, y)if i == 31:l31.set_data(x, y)if i == 32:l32.set_data(x, y)if i == 133:l33.set_data(x, y)if i == 34:l34.set_data(x, y)if i == 35:l35.set_data(x, y)if i == 36:l36.set_data(x, y)if i == 37:l37.set_data(x, y)if i == 38:l38.set_data(x, y)if i == 39:l39.set_data(x, y)if i == 40:l40.set_data(x, y)def pin_update3(n, e, d, D, phi):for i in range(int(n)):x = (d/2*np.sin(t) + D/2*np.cos(2*i*np.pi/n))*np.cos(-phi/(n)) - \(d/2*np.cos(t) + D/2*np.sin(2*i*np.pi/n)) * \np.sin(-phi/(n)) + e*np.cos(phi)y = (d/2*np.sin(t) + D/2*np.cos(2*i*np.pi/n))*np.sin(-phi/(n)) + \(d/2*np.cos(t) + D/2*np.sin(2*i*np.pi/n)) * \np.cos(-phi/(n)) + e*np.sin(phi)if i == 0:l0.set_data(x, y)if i == 1:l1.set_data(x, y)if i == 2:l2.set_data(x, y)if i == 3:l3.set_data(x, y)if i == 4:l4.set_data(x, y)if i == 5:l5.set_data(x, y)if i == 6:l6.set_data(x, y)if i == 7:l7.set_data(x, y)if i == 8:l8.set_data(x, y)if i == 9:l9.set_data(x, y)if i == 10:l10.set_data(x, y)if i == 11:l11.set_data(x, y)if i == 12:l12.set_data(x, y)if i == 13:l13.set_data(x, y)if i == 14:l14.set_data(x, y)if i == 15:l15.set_data(x, y)if i == 16:l16.set_data(x, y)if i == 17:l17.set_data(x, y)if i == 18:l18.set_data(x, y)if i == 19:l19.set_data(x, y)if i == 20:l20.set_data(x, y)if i == 21:l21.set_data(x, y)if i == 22:l22.set_data(x, y)if i == 23:l23.set_data(x, y)if i == 24:l24.set_data(x, y)if i == 25:l25.set_data(x, y)if i == 26:l26.set_data(x, y)if i == 27:l27.set_data(x, y)if i == 28:l28.set_data(x, y)if i == 29:l29.set_data(x, y)if i == 30:l30.set_data(x, y)if i == 31:l31.set_data(x, y)if i == 32:l32.set_data(x, y)if i == 133:l33.set_data(x, y)if i == 34:l34.set_data(x, y)if i == 35:l35.set_data(x, y)if i == 36:l36.set_data(x, y)if i == 37:l37.set_data(x, y)if i == 38:l38.set_data(x, y)if i == 39:l39.set_data(x, y)if i == 40:l40.set_data(x, y)# draw inner_pinp0, = ax.plot([], [], 'g-', lw=2)p1, = ax.plot([], [], 'g-', lw=2)p2, = ax.plot([], [], 'g-', lw=2)p3, = ax.plot([], [], 'g-', lw=2)p4, = ax.plot([], [], 'g-', lw=2)p5, = ax.plot([], [], 'g-', lw=2)p6, = ax.plot([], [], 'g-', lw=2)p7, = ax.plot([], [], 'g-', lw=2)p8, = ax.plot([], [], 'g-', lw=2)p9, = ax.plot([], [], 'g-', lw=2)for i in range(int(6)):x = (5*np.sin(t) + 20*np.cos(2*i*np.pi/6))y = (5*np.cos(t) + 20*np.sin(2*i*np.pi/6))if i == 0:p0, = ax.plot(x, y, 'g-')if i == 1:p1, = ax.plot(x, y, 'g-')if i == 2:p2, = ax.plot(x, y, 'g-')if i == 3:p3, = ax.plot(x, y, 'g-')if i == 4:p4, = ax.plot(x, y, 'g-')if i == 5:p5, = ax.plot(x, y, 'g-')if i == 6:p6, = ax.plot(x, y, 'g-')if i == 7:p7, = ax.plot(x, y, 'g-')if i == 8:p8, = ax.plot(x, y, 'g-')if i == 9:p9, = ax.plot(x, y, 'g-')def inner_pin_update(n, N, rd, Rd, phi):for i in range(int(n)):x = (rd*np.sin(t) + Rd*np.cos(2*i*np.pi/n))*np.cos(-phi/(N-1)) - \(rd*np.cos(t) + Rd*np.sin(2*i*np.pi/n))*np.sin(-phi/(N-1))y = (rd*np.sin(t) + Rd*np.cos(2*i*np.pi/n))*np.sin(-phi/(N-1)) + \(rd*np.cos(t) + Rd*np.sin(2*i*np.pi/n))*np.cos(-phi/(N-1))if i == 0:p0.set_data(x, y)if i == 1:p1.set_data(x, y)if i == 2:p2.set_data(x, y)if i == 3:p3.set_data(x, y)if i == 4:p4.set_data(x, y)if i == 5:p5.set_data(x, y)if i == 6:p6.set_data(x, y)if i == 7:p7.set_data(x, y)if i == 8:p8.set_data(x, y)if i == 9:p9.set_data(x, y)# draw drive_pina = 5*np.sin(t)b = 5*np.cos(t)d0, = ax.plot(a, b, 'k-', lw=2)def drive_pin_update(r):x = r*np.sin(t)y = r*np.cos(t)d0.set_data(x, y)# inner circle:inner_circle1, = ax.plot([], [], 'r-', lw=2)inner_circle2, = ax.plot([], [], 'r-', lw=2)inner_circle3, = ax.plot([], [], 'r-', lw=2)inner_circle4, = ax.plot([], [], 'r-', lw=2)inner_circle5, = ax.plot([], [], 'r-', lw=2)inner_circle6, = ax.plot([], [], 'r-', lw=2)inner_circle7, = ax.plot([], [], 'r-', lw=2)inner_circle8, = ax.plot([], [], 'r-', lw=2)inner_circle9, = ax.plot([], [], 'r-', lw=2)inner_circle10, = ax.plot([], [], 'r-', lw=2)def draw_inner_circle_init():inner_circle10.set_data([0], [0])inner_circle1.set_data([0], [0])inner_circle2.set_data([0], [0])inner_circle3.set_data([0], [0])inner_circle4.set_data([0], [0])inner_circle5.set_data([0], [0])inner_circle6.set_data([0], [0])inner_circle7.set_data([0], [0])inner_circle8.set_data([0], [0])inner_circle9.set_data([0], [0])for i in range(6):x = (rd+e)*np.cos(t)+0.5*RD*np.cos(2*i*np.pi/6)+ey = (rd+e)*np.sin(t)+0.5*RD*np.sin(2*i*np.pi/6)if i == 0:inner_circle1, = ax.plot(x, y, 'r-')if i == 1:inner_circle2, = ax.plot(x, y, 'r-')if i == 2:inner_circle3, = ax.plot(x, y, 'r-')if i == 3:inner_circle4, = ax.plot(x, y, 'r-')if i == 4:inner_circle5, = ax.plot(x, y, 'r-')if i == 5:inner_circle6, = ax.plot(x, y, 'r-')if i == 6:inner_circle7, = ax.plot(x, y, 'r-')if i == 7:inner_circle8, = ax.plot(x, y, 'r-')if i == 8:inner_circle9, = ax.plot(x, y, 'r-')if i == 9:inner_circle10, = ax.plot(x, y, 'r-')def update_inner_circle(e, n, N, rd, Rd, phi):for i in range(int(n)):x = ((rd+e)*np.cos(t)+Rd*np.cos(2*i*np.pi/n))*np.cos(-phi/(N-1)) - ((rd+e)* np.sin(t)+Rd*np.sin(2*i*np.pi/n))*np.sin(-phi/(N-1)) + e*np.cos(phi)y = ((rd+e)*np.cos(t)+Rd*np.cos(2*i*np.pi/n))*np.sin(-phi/(N-1)) + ((rd+e)* np.sin(t)+Rd*np.sin(2*i*np.pi/n))*np.cos(-phi/(N-1)) + e*np.sin(phi)if i == 0:inner_circle1.set_data(x, y)if i == 1:inner_circle2.set_data(x, y)if i == 2:inner_circle3.set_data(x, y)if i == 3:inner_circle4.set_data(x, y)if i == 4:inner_circle5.set_data(x, y)if i == 5:inner_circle6.set_data(x, y)if i == 6:inner_circle7.set_data(x, y)if i == 7:inner_circle8.set_data(x, y)if i == 8:inner_circle9.set_data(x, y)if i == 9:inner_circle10.set_data(x, y)# inner pinA:x = (rd+e)*np.cos(t)+ey = (rd+e)*np.sin(t)inner_pinA, = ax.plot(x, y, 'r-')# driver line and dot:#self.line, = self.ax.plot([self.rd+self.e + self.e, 0],[0,0],'r-')dotA, = ax.plot([-rd - e - e], [0], 'ro', ms=5)def update_inner_pinA(e, Rm, phi):x = (Rm+e+e)*np.cos(t)+2*e*np.cos(phi)y = (Rm+e+e)*np.sin(t)+2*e*np.sin(phi)inner_pinA.set_data(x, y)x1 = (Rm+e+e)*np.cos(phi)+2*e*np.cos(phi)y1 = (Rm+e+e)*np.sin(phi)+2*e*np.sin(phi)# self.line.set_data([0,x1],[0,y1])dotA.set_data(x1, y1)# inner pinD:#x = (rd+e)*np.cos(t)-e#y = (rd+e)*np.sin(t)#inner_pinD, = ax.plot(x,y,'b-')# driver line and dot:#self.line, = self.ax.plot([self.rd+self.e + self.e, 0],[0,0],'r-')#dotD, = ax.plot([-rd- e- e],[0], 'bo', ms=5)# def update_inner_pinD(e,Rm, phi):# x = (Rm+e)*np.cos(t)-e*np.cos(phi)# y = (Rm+e)*np.sin(t)-e*np.sin(phi)# # inner_pinD.set_data(x,y)# x1 = (Rm+e)*np.cos(phi+np.pi)-e*np.cos(phi)# y1 = (Rm+e)*np.sin(phi+np.pi)-e*np.sin(phi)# self.line.set_data([0,x1],[0,y1])# dotD.set_data(x1, y1)# ehypocycloidA:rc = (n-1)*(RD/n)rm = (RD/n)xa = (rc+rm)*np.cos(t)-e*np.cos((rc+rm)/rm*t)ya = (rc+rm)*np.sin(t)-e*np.sin((rc+rm)/rm*t)dxa = (rc+rm)*(-np.sin(t)+(e/rm)*np.sin((rc+rm)/rm*t))dya = (rc+rm)*(np.cos(t)-(e/rm)*np.cos((rc+rm)/rm*t))x = xa + rd/np.sqrt(dxa**2 + dya**2)*(-dya) + 2*ey = ya + rd/np.sqrt(dxa**2 + dya**2)*dxaehypocycloidA, = ax.plot(x, y, 'r-')# driver line and dot: (rc+rm) - rd#self.eline, = self.ax.plot([(rc+rm) - rd, 0],[0,0],'r-')edotA, = ax.plot([(rc+rm) - rd], [0], 'ro', ms=5)def update_ehypocycloidA(e, n, D, d, phis):RD = D/2rd = d/2rc = (n-1)*(RD/n)rm = (RD/n)xa = (rc+rm)*np.cos(t)-e*np.cos((rc+rm)/rm*t)ya = (rc+rm)*np.sin(t)-e*np.sin((rc+rm)/rm*t)dxa = (rc+rm)*(-np.sin(t)+(e/rm)*np.sin((rc+rm)/rm*t))dya = (rc+rm)*(np.cos(t)-(e/rm)*np.cos((rc+rm)/rm*t))#x = (xa + rd/np.sqrt(dxa**2 + dya**2)*(-dya))*np.cos(phis/(n-1))-(ya + rd/np.sqrt(dxa**2 + dya**2)*dxa)*np.sin(phis/(n-1)) + e*np.cos(-phis) + e#y = (xa + rd/np.sqrt(dxa**2 + dya**2)*(-dya))*np.sin(phis/(n-1))+(ya + rd/np.sqrt(dxa**2 + dya**2)*dxa)*np.cos(phis/(n-1)) + e*np.sin(-phis)# ehypocycloidA.set_data(x,y)x = (xa + rd/np.sqrt(dxa**2 + dya**2)*(-dya))*np.cos(-2*phis/(n-1))-(ya +rd/np.sqrt(dxa**2 + dya**2)*dxa)*np.sin(-2*phis/(n-1)) + 2*e*np.cos(phis)y = (xa + rd/np.sqrt(dxa**2 + dya**2)*(-dya))*np.sin(-2*phis/(n-1))+(ya +rd/np.sqrt(dxa**2 + dya**2)*dxa)*np.cos(-2*phis/(n-1)) + 2*e*np.sin(phis)ehypocycloidA.set_data(x, y)# self.eline.set_data([e*np.cos(phis),x[0]],[e*np.sin(phis),y[0]])edotA.set_data(x[0], y[0])# ehypocycloidD:rc = (n+1)*(RD/n)rm = (RD/n)xa = (rc-rm)*np.cos(t)+e*np.cos((rc-rm)/rm*t)ya = (rc-rm)*np.sin(t)-e*np.sin((rc-rm)/rm*t)dxa = (rc-rm)*(-np.sin(t)-(e/rm)*np.sin((rc-rm)/rm*t))dya = (rc-rm)*(np.cos(t)-(e/rm)*np.cos((rc-rm)/rm*t))#x = xa - rd/np.sqrt(dxa**2 + dya**2)*(-dya) - e#y = ya - rd/np.sqrt(dxa**2 + dya**2)*dxax = xa - rd/np.sqrt(dxa**2 + dya**2)*(-dya)y = ya - rd/np.sqrt(dxa**2 + dya**2)*dxaehypocycloidD, = ax.plot(x, y, 'b-')# driver line and dot: (rc+rm) - rd#self.eline, = self.ax.plot([(rc+rm) - rd, 0],[0,0],'r-')edotD, = ax.plot([(rc+rm) - rd + e], [0], 'bo', ms=5)def update_ehypocycloidD(e, n, D, d, phis):RD = D/2rd = d/2rc = (n+1)*(RD/n)rm = (RD/n)xa = (rc-rm)*np.cos(t)+e*np.cos((rc-rm)/rm*t)ya = (rc-rm)*np.sin(t)-e*np.sin((rc-rm)/rm*t)dxa = (rc-rm)*(-np.sin(t)-(e/rm)*np.sin((rc-rm)/rm*t))dya = (rc-rm)*(np.cos(t)-(e/rm)*np.cos((rc-rm)/rm*t))x = (xa - rd/np.sqrt(dxa**2 + dya**2)*(-dya))y = (ya - rd/np.sqrt(dxa**2 + dya**2)*dxa)ehypocycloidD.set_data(x, y)# self.eline.set_data([e*np.cos(phis),x[0]],[e*np.sin(phis),y[0]])edotD.set_data(x[0], y[0])axcolor = 'lightgoldenrodyellow'ax_fm = plt.axes([0.25, 0.27, 0.5, 0.02], facecolor=axcolor)ax_Rm = plt.axes([0.25, 0.24, 0.5, 0.02], facecolor=axcolor)ax_n = plt.axes([0.25, 0.21, 0.5, 0.02], facecolor=axcolor)ax_Rd = plt.axes([0.25, 0.18, 0.5, 0.02], facecolor=axcolor)ax_rd = plt.axes([0.25, 0.15, 0.5, 0.02], facecolor=axcolor)ax_e = plt.axes([0.25, 0.12, 0.5, 0.02], facecolor=axcolor)ax_N = plt.axes([0.25, 0.09, 0.5, 0.02], facecolor=axcolor)ax_d = plt.axes([0.25, 0.06, 0.5, 0.02], facecolor=axcolor)ax_D = plt.axes([0.25, 0.03, 0.5, 0.02], facecolor=axcolor)sli_fm = Slider(ax_fm, 'fm', 10, 100, valinit=50, valstep=delta)sli_Rm = Slider(ax_Rm, 'Rm', 1, 10, valinit=5, valstep=delta)sli_n = Slider(ax_n, 'n', 3, 10, valinit=6, valstep=delta)sli_Rd = Slider(ax_Rd, 'Rd', 1, 40, valinit=20, valstep=delta)sli_rd = Slider(ax_rd, 'rd', 1, 10, valinit=5, valstep=delta)sli_e = Slider(ax_e, 'e', 0.1, 10, valinit=2, valstep=delta/10)sli_N = Slider(ax_N, 'N', 3, 40, valinit=10, valstep=delta)sli_d = Slider(ax_d, 'd', 2, 20, valinit=10, valstep=delta)sli_D = Slider(ax_D, 'D', 5, 100, valinit=80, valstep=delta)def update(val):sfm = sli_Rm.valsRm = sli_Rm.valsRd = sli_Rd.valsn = sli_n.valsrd = sli_rd.valse = sli_e.valsN = sli_N.valsd = sli_d.valsD = sli_D.valax.set_xlim(-1.4*0.5*sD, 1.4*0.5*sD)ax.set_ylim(-1.4*0.5*sD, 1.4*0.5*sD)sli_fm.on_changed(update)sli_Rm.on_changed(update)sli_Rd.on_changed(update)sli_n.on_changed(update)sli_rd.on_changed(update)sli_e.on_changed(update)sli_N.on_changed(update)sli_d.on_changed(update)sli_D.on_changed(update)resetax = plt.axes([0.85, 0.01, 0.1, 0.04])button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975')def reset(event):sli_fm.reset()sli_Rm.reset()sli_n.reset()sli_rd.reset()sli_Rd.reset()sli_e.reset()sli_N.reset()sli_d.reset()sli_D.reset()button.on_clicked(reset)def animate(frame):sfm = sli_fm.valsRm = sli_Rm.valsRd = sli_Rd.valsn = sli_n.valsrd = sli_rd.valse = sli_e.valsN = sli_N.valsd = sli_d.valsD = sli_D.valframe = frame+1phi = 2*np.pi*frame/sfmdraw_pin_init()draw_inner_pin_init()draw_inner_circle_init()pin_update3(sN, se, sd, sD, phi)update_inner_pinA(se, sRm, phi)#update_inner_pinD(se,sRm, phi)# inner_pin_update(sn,sN,srd,sRd,phi)# drive_pin_update(sRm)#update_inner_circle(se,sn,sN,srd,sRd, phi)update_ehypocycloidA(se, sN, sD, sd, phi)update_ehypocycloidD(se, sN, sD, sd, phi)fig.canvas.draw_idle()ani = animation.FuncAnimation(fig, animate, frames=sli_fm.val*(sli_N.val-1), interval=interval)dpi = 100# un-comment the next line, if you want to save the animation as gif:#hypo.animation.save('myhypocycloid.gif', writer='pillow', fps=10, dpi=75)#ani.save('myGUI1.mp4', writer="ffmpeg",dpi=dpi)plt.show()
這里是一段python的算法仿真

算法仿真的結果

結果
intel? RealSense? D450深度攝像頭也是硬件之一,這個東西好像2k
https://www.intel.cn/content/www/cn/zh/products/sku/126367/intel-realsense-vision-processor-d4/downloads.html在這里是我找到了攝像頭的相關固件和驅動的下載位置
我也沒有這個攝像頭只能這樣的云體驗了

這是現在的價錢

正面

這個是相機的底面,標準的螺紋管以及Type-C的接口

一些硬件參數

以及對應要求的一些驅動主機的基本要求,其實還是主要看接口
USB3.0的速度確實是會快很多
https://www.intelrealsense.com/sdk-2/這里是它的SDK的位置
https://dev.intelrealsense.com/docs這里是它的教程位置,我覺得寫的很豐富

攢錢買個硬件就好了,這個這個好哦!

matlab的demo也也有
function depth_example()% Make Pipeline object to manage streamingpipe = realsense.pipeline();% Make Colorizer object to prettify depth outputcolorizer = realsense.colorizer();% Start streaming on an arbitrary camera with default settingsprofile = pipe.start();% Get streaming device's namedev = profile.get_device();name = dev.get_info(realsense.camera_info.name);% Get frames. We discard the first couple to allow% the camera time to settlefor i = 1:5fs = pipe.wait_for_frames();end% Stop streamingpipe.stop();% Select depth framedepth = fs.get_depth_frame();% Colorize depth framecolor = colorizer.colorize(depth);% Get actual data and convert into a format imshow can use% (Color data arrives as [R, G, B, R, G, B, ...] vector)data = color.get_data();img = permute(reshape(data',[3,color.get_width(),color.get_height()]),[3 2 1]);% Display imageimshow(img);title(sprintf("Colorized depth frame from %s", name));end
matlab的讀取函數
# Create a context object. This object owns the handles to all connected realsense devicespipeline = rs.pipeline()pipeline.start()try:while True:# Create a pipeline object. This object configures the streaming camera and owns it's handleframes = pipeline.wait_for_frames()depth = frames.get_depth_frame()if not depth: continue# Print a simple text-based representation of the image, by breaking it into 10x20 pixel regions and approximating the coverage of pixels within one metercoverage = [0]*64for y in xrange(480):for x in xrange(640):dist = depth.get_distance(x, y)if 0 < dist and dist < 1:coverage[x/10] += 1if y%20 is 19:line = ""for c in coverage:line += " .:nhBXWW"[c/25]coverage = [0]*64print(line)finally:pipeline.stop()
python的腳本還是看起來比較簡單的。
為了讓處理的數據更快,可以使用numpy來構造一個數組
import numpy as npdepth = frames.get_depth_frame()depth_data = depth.as_frame().get_data()np_image = np.asanyarray(depth_data)
因為Liberelease幀支持緩沖協議,所以可以使用numpy來這樣處理。
機械狗上面都運行著,機器人操作系統ROS(Robotics Operating System)
本次的CyberDog運行的是ROS2

ROS2的構架圖
http://doc.tianbot.com/ros2go/http://ros2.bwbot.org/tourial/about-ros2/ros-concepts.html文檔地址

這個是要仿照的元祖
波士頓動力的機器人并不過分追求毫厘之間的精確度,追求的是功能的精確性。Atlas 是亞穩態的,因此它在絕大多數時候都是穩定的。處于亞穩態,意味著 Atlas 需要像人類一樣保持直立。但即便是 Atlas 所做的后空翻,也只需要 “非常粗略的計算”。當它著陸時,它會對計算做出修正,不需要完美無缺,足夠好就行了。其實就是落地的時候有很多的不確定性相當于一個解空間,我們只要選擇一個相對比較好的解就好,不需要滿足一個定解,在后期進行短暫的修正即可。這樣的想法也符合我們人的運動學做法。
眾所周知,動物最常見的運動方式是節律運動,即按照。一定的節奏、有力度地重復、協調、持續進行的動作,是低級神經中樞的自激行為。生物學上,動物的節律運動控制區被認為是分層并且模塊化的,其控制以中樞模式發生器為中心,既可以接受來自高層的高級神經中樞的主觀控制,也可以響應來自軀體各種感受器官的反射,這就是CPG控制機理,也就是所謂的中樞神經發生器。前人已經按照CPG控制機理建立了不同形式的數學模型,它們能夠產生的周期振蕩的信號,使其能夠滿足節律運動的特點。

具體的可以去相關論文

我參考的是這篇
基于神經元的模型:Matsuoka神經元震蕩模型、Kimura模型等,該類模型生物學意義明確,但參數較多,動態特性分析比較復雜。
基于非線性振蕩器的模型:Kuramoto相位振蕩器、Hopf諧波振蕩器等,該類模型參數較少,模型比較成熟。
https://xw.qq.com/cmsid/20191101A0L4OB00原文在這里

Atlas,跑起來很吊的樣子

機械外骨骼
其實這么多年了,并不是只有小米一家發布的機器狗,只不過是小米家的狗攤上了雷軍,會營銷。也就是所謂的出生好。
| 浙大“絕影”機器狗 |
| 騰訊機器狗Max |
| 宇樹科技機器狗 |
| 優必選四足機器人“拓荒牛” |
| 蔚藍科技阿爾法機器狗 |
最近幾年其實出現了這么多的狗,各有其獨特的特點,而且普遍都貴。就是賣不出去。而米家的東西一向追求性價比,所以9999是一個很有誠意的價格。

宇樹科技是一個2016年成立的年輕公司

也有自己的拳頭產品

一些特性

負載3~5kg

air版本1.6,均衡1.99,edu5萬起。
米家1w的東西又是屠龍刀了
https://www.unitree.com/cn/products/go1
宇樹家的東西比較齊全

相關的配置

豐富的接口,為什么沒有RJ-45
https://www.unitree.com/cn/products/a1我最喜歡的還是A1


開放的接口,一看就是兩套開發板

接口框圖
https://github.com/unitreerobotics
開源了許多了庫,沒啥有價值的
又不開源算法
總的來說,小米的東西可能性能不是那么好,算法不是最優。但是它一定是價錢最低,處于一種剛剛好的情況。也不知道就像小米的無人機一樣是曇花一現,希望不是。
而且這個1w的價錢真的很便宜,就是我窮而已。也希望小米的逐步開源,我在這邊也會持續的跟進。
來自斯坦福的廉價機器狗.上
來自斯坦福的廉價機器狗.中
我以前也寫過一些機械狗的東西,只不過后來又更快樂的事情了,就鴿了。

因為每天有很多人在問問題,所以就建立了一個交流群
有需要的可以加進來一起學習