Add AC/BC RTCP programs and 3D machine manager
This commit is contained in:
103
scripts/generate_rtcp_beginner_figures.py
Normal file
103
scripts/generate_rtcp_beginner_figures.py
Normal file
@@ -0,0 +1,103 @@
|
||||
"""Original diagrams for the beginner's work-coordinate handbook."""
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
import matplotlib
|
||||
matplotlib.use('Agg')
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib import font_manager
|
||||
from matplotlib.patches import Rectangle, Polygon
|
||||
import numpy as np
|
||||
|
||||
ROOT=Path(__file__).resolve().parents[1]
|
||||
OUT=ROOT/'docs/teaching/rtcp-beginners/assets';OUT.mkdir(parents=True,exist_ok=True)
|
||||
font_manager.fontManager.addfont('/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc')
|
||||
plt.rcParams.update({'font.family':'Noto Sans CJK JP','font.size':14,'axes.unicode_minus':False})
|
||||
BLUE,TEAL,RED,GRAY,INK='#2563b8','#00877b','#d45549','#8a969f','#23303a'
|
||||
for name in ['machine-ac','machine-bc','hierarchy','identity-no-follow','tcp-follow','rotated-direction','bc-frame','pivot-offset','arc-chord','tool-length','orientation']:
|
||||
shutil.copyfile(ROOT/f'docs/teaching/rtcp-five-axis/assets/{name}.png',OUT/f'{name}.png')
|
||||
def save(fig,name):
|
||||
fig.savefig(OUT/f'{name}.png',dpi=190,facecolor='white',bbox_inches='tight',pad_inches=.18);plt.close(fig)
|
||||
def arrow(ax,start,end,color,label='',dx=0,dy=0):
|
||||
ax.annotate('',end,start,arrowprops={'arrowstyle':'-|>','lw':2,'color':color})
|
||||
if label:ax.text(end[0]+dx,end[1]+dy,label,color=color,fontsize=14)
|
||||
|
||||
fig,ax=plt.subplots(figsize=(8,4.2));ax.set(xlim=(-8,55),ylim=(-8,38),aspect='equal');ax.axis('off')
|
||||
for x in range(0,51,10):ax.plot([x,x],[0,30],c='#dce6ec',lw=1);ax.text(x,-4,str(x),ha='center',fontsize=12,color=GRAY)
|
||||
for y in range(0,31,10):ax.plot([0,50],[y,y],c='#dce6ec',lw=1);ax.text(-4,y,str(y),va='center',fontsize=12,color=GRAY)
|
||||
arrow(ax,(0,0),(54,0),BLUE,'X',-1,-5);arrow(ax,(0,0),(0,36),BLUE,'Y',-5,-1)
|
||||
ax.scatter([30],[20],s=90,color=RED);ax.plot([30,30,0],[0,20,20],ls='--',color=RED,lw=1.5)
|
||||
ax.text(32,22,'P = (30, 20) mm',color=RED);ax.text(2,32,'先选原点,再沿指定方向量距离',fontsize=14,color=INK)
|
||||
save(fig,'coordinate-grid')
|
||||
|
||||
fig,ax=plt.subplots(figsize=(8,4.4));ax.set(xlim=(-10,95),ylim=(-10,60),aspect='equal');ax.axis('off')
|
||||
arrow(ax,(0,0),(90,0),BLUE,'X_M',-8,-7);arrow(ax,(0,0),(0,56),BLUE,'Y_M',-8,-2)
|
||||
arrow(ax,(40,20),(79,20),TEAL,'X_W',0,-2);arrow(ax,(40,20),(40,54),TEAL,'Y_W',2,0)
|
||||
ax.scatter([50],[35],s=95,color=RED);ax.text(54,38,'同一个点 P',color=RED)
|
||||
ax.plot([50,50,40],[20,35,35],ls='--',color=TEAL);ax.text(43,24,'10',color=TEAL);ax.text(32,27,'15',color=TEAL)
|
||||
ax.annotate('O_W 在 M 中为 (40,20)',(40,20),xytext=(23,6),fontsize=12,arrowprops={'arrowstyle':'->','color':GRAY})
|
||||
ax.text(3,46,'P_M=(50,35)\nP_W=(10,15)',fontsize=15,color=INK)
|
||||
save(fig,'same-point')
|
||||
|
||||
fig,axes=plt.subplots(1,2,figsize=(10,5))
|
||||
for ax,c in zip(axes,[0,90]):
|
||||
ax.set(xlim=(-55,85),ylim=(-28,95),aspect='equal');ax.axis('off')
|
||||
arrow(ax,(0,0),(78,0),BLUE,'X_M',-5,-12);arrow(ax,(0,0),(0,85),BLUE,'Y_M',-18,-1)
|
||||
rad=np.deg2rad(c);r=np.array([[np.cos(rad),-np.sin(rad)],[np.sin(rad),np.cos(rad)]])
|
||||
o=r@np.array([40,20]);point=r@np.array([50,20]);x=r@np.array([25,0]);y=r@np.array([0,25])
|
||||
poly=np.array([o+r@np.array(v) for v in [[-5,-5],[30,-5],[30,20],[-5,20]]]);ax.add_patch(Polygon(poly,fc='#e1f2ee',ec=TEAL,alpha=.65))
|
||||
arrow(ax,o,o+x,TEAL,'X_W',2,0);arrow(ax,o,o+y,TEAL,'Y_W',2,0)
|
||||
ax.scatter(*o,color=TEAL,s=70);ax.scatter(*point,color=RED,s=100,marker='*')
|
||||
ax.text(-48,89,f'C = {c}°',color=INK,fontsize=17)
|
||||
ax.text(-48,-23,f'O_M=({o[0]:.0f},{o[1]:.0f})\nP_M=({point[0]:.0f},{point[1]:.0f})',color=INK,fontsize=13)
|
||||
label_position=(12,57) if c else (-45,67)
|
||||
ax.annotate('P:X10,Y0',point,xytext=label_position,arrowprops={'arrowstyle':'->','color':RED},color=RED,fontsize=12)
|
||||
fig.subplots_adjust(wspace=.15)
|
||||
save(fig,'moving-origin')
|
||||
|
||||
fig,ax=plt.subplots(figsize=(8,4.5));ax.axis('off');ax.set(xlim=(-10,120),ylim=(-15,80),aspect='equal')
|
||||
front=np.array([[10,15],[85,15],[85,38],[10,38]]);side=np.array([[85,15],[108,37],[108,60],[85,38]]);top=np.array([[10,38],[85,38],[108,60],[33,60]])
|
||||
for poly,color in [(front,'#d4e3e8'),(side,'#b9cdd3'),(top,'#e5f2ef')]:ax.add_patch(Polygon(poly,fc=color,ec=GRAY))
|
||||
origin=(10,38);arrow(ax,origin,(66,38),TEAL,'+X',0,-7);arrow(ax,origin,(33,60),TEAL,'+Y',-4,7);arrow(ax,origin,(10,72),TEAL,'+Z',2,0)
|
||||
ax.scatter(*origin,color=RED,s=70);ax.annotate('示例:顶面左前角为零点',origin,xytext=(5,2),arrowprops={'arrowstyle':'->','color':RED},color=RED,fontsize=14)
|
||||
ax.scatter([65],[48],color=BLUE,s=130,facecolors='none');ax.annotate('也可选孔中心\n必须与CAD/CAM约定一致',(65,48),xytext=(75,74),arrowprops={'arrowstyle':'->','color':BLUE},color=BLUE,fontsize=12)
|
||||
save(fig,'datum-choice')
|
||||
|
||||
fig,ax=plt.subplots(figsize=(8,4.5));ax.axis('off');ax.set(xlim=(-20,110),ylim=(-20,85),aspect='equal')
|
||||
o=np.array([15,8]);a=np.deg2rad(20);u=np.array([np.cos(a),np.sin(a)]);v=np.array([-np.sin(a),np.cos(a)])
|
||||
pts=[o,o+u*75,o+v*45]
|
||||
ax.plot([pts[1][0],o[0],pts[2][0]],[pts[1][1],o[1],pts[2][1]],color=TEAL,lw=2)
|
||||
for p,label,dx,dy in zip(pts,['O:所选原点','P_x:确定 +X','P_y:确定 XY 面'],[-12,2,-10],[-12,0,6]):ax.scatter(*p,s=80,color=RED);ax.text(p[0]+dx,p[1]+dy,label,fontsize=13,color=INK)
|
||||
arrow(ax,o,o+u*93,TEAL,'+X',0,0);arrow(ax,o,o+v*62,TEAL,'+Y',-5,3)
|
||||
arrow(ax,(-8,-9),(100,-9),BLUE,'机床 X',-25,-8)
|
||||
ax.text(48,64,'工件不能只靠“一个点”\n确定全部方向',color=INK,fontsize=15,ha='center')
|
||||
save(fig,'orientation-measure')
|
||||
|
||||
fig,axes=plt.subplots(2,1,figsize=(8,3.6))
|
||||
for ax,title,target in zip(axes,['当前位置 X=10,G90 X20','当前位置 X=10,G91 X20'],[20,30]):
|
||||
ax.set(xlim=(-3,39),ylim=(-1,6));ax.axis('off');arrow(ax,(0,1),(37,1),BLUE)
|
||||
for x in [0,10,20,30]:ax.plot([x,x],[.8,1.2],color=GRAY);ax.text(x,-.2,str(x),ha='center',fontsize=13)
|
||||
ax.text(0,4,title,fontsize=15,color=INK);ax.scatter([10],[1],color=GRAY,s=70);ax.scatter([target],[1],color=RED,s=90)
|
||||
arrow(ax,(10,2),(target,2),RED);ax.text((10+target)/2,2.8,f'实际移动 {target-10}',ha='center',color=RED,fontsize=12)
|
||||
fig.subplots_adjust(hspace=.35);save(fig,'absolute-incremental')
|
||||
|
||||
fig,ax=plt.subplots(figsize=(8,4));ax.axis('off');ax.set(xlim=(0,10),ylim=(0,5))
|
||||
rows=[('① 程序工件点 W','(10, 0, 5)',TEAL),('② 加 G54 零位偏置','+(40, 20, 10)',GRAY),('③ 运动学输入 K','(50, 20, 15)',BLUE),('④ C=90°,RTCP变换','(-20, 50, 15)',RED)]
|
||||
for i,(label,value,color) in enumerate(rows):
|
||||
y=4.15-i*1.06;ax.add_patch(Rectangle((.3,y-.34),9.3,.74,fc='#eef4f6',ec='none'))
|
||||
ax.text(.55,y,label,color=color,fontsize=15,va='center');ax.text(6.1,y,value,color=color,fontsize=16,va='center')
|
||||
if i<3:ax.text(5,y-.58,'↓',ha='center',va='center',color=GRAY)
|
||||
save(fig,'offset-pipeline')
|
||||
|
||||
c=np.linspace(0,90,181);r=np.deg2rad(c);qx=50*np.cos(r)-20*np.sin(r);qy=50*np.sin(r)+20*np.cos(r)
|
||||
fig,ax=plt.subplots(figsize=(8,4));ax.plot(c,qx,color=BLUE,lw=2.4,label='关节 X');ax.plot(c,qy,color=TEAL,lw=2.4,label='关节 Y');ax.plot(c,np.full_like(c,15),color=RED,lw=2.4,label='关节 Z')
|
||||
ax.set(xlabel='C 角度(°)',ylabel='关节位置(mm)',xlim=(0,90));ax.grid(alpha=.2);ax.legend(loc='lower left',ncol=3,fontsize=12);ax.set_title('程序 X10 Y0 Z5 保持;关节由RTCP连续计算',fontsize=15,color=INK)
|
||||
fig.tight_layout();save(fig,'continuous-joints')
|
||||
|
||||
fig,ax=plt.subplots(figsize=(6.7,4.1));ax.set(aspect='equal',xlim=(-3,14),ylim=(-3,14));ax.axis('off')
|
||||
arrow(ax,(0,0),(13,0),BLUE,'X',0,-1);arrow(ax,(0,0),(0,13),BLUE,'Y',-1,0)
|
||||
t=np.linspace(0,np.pi/2,100);ax.plot(10*np.cos(t),10*np.sin(t),color=TEAL,lw=3)
|
||||
arrow(ax,(8.5,5.27),(7.8,6.25),TEAL);ax.scatter([10,0,0],[0,10,0],color=[RED,TEAL,GRAY],s=80)
|
||||
ax.text(6.8,-1.8,'起点 (10,0)',color=RED,fontsize=13);ax.text(.8,10.5,'终点 (0,10)',color=TEAL,fontsize=13)
|
||||
ax.text(2.8,3.5,'圆心 (0,0)\nI=-10,J=0',color=INK,fontsize=14)
|
||||
ax.plot([10,0],[0,0],ls=':',color=GRAY,lw=2);save(fig,'arc-words')
|
||||
print('Created 9 new diagrams and reused 11 verified original assets:',OUT)
|
||||
Reference in New Issue
Block a user