python的先进制造技术工业场景模拟第二十七篇:加载机器人标定误差数据集,计算标定前后定位误差的改善幅度。
周二下午,机器人调试间。
"标定做完了,可我不知道到底改善了多少,"调试员小赵把两份 CSV 甩在桌上,"一份是标定前,一份是标定后,每个点位记录了实际坐标和理论坐标,差值就是误差。可二十个点位,每个点位 XYZ 三个方向,我怎么跟工艺科说'标定有效'?"
我点开文件。
"这表里有什么?"小赵问。
"每个点位一行,理论坐标 X/Y/Z,实际坐标 X/Y/Z,标定前一份、标定后一份,"我指着数据,"问题是你只看了某几个点的单轴误差,没算整体定位误差的统计量。"
"我就想干一件事,"小赵说,"把标定前后的定位误差做个对比——均值降了多少、最大误差降了多少、每个方向的改善幅度、有没有哪个点位改善不明显甚至变差了。最好画个图,让工艺科一眼看出来标定值不值。"
"比如点位 P05,标定前误差 2.1mm,标定后 0.4mm,降了 80%,"我接话,"但点位 P12 标定前 1.8mm,标定后 1.5mm,只降了 16%,那就要看是不是那个位置关节柔性大,或者标定参数没覆盖到。"
"对,"小赵点头,"还有,我想看 XYZ 三个方向各自改善了多少,是不是某个方向标定效果特别差。以前只能说'差不多准了',现在要拿数据说话。"
"用 pandas 读两份标定数据,numpy 算欧氏距离误差向量,scipy 做配对 t 检验验证改善显著性,matplotlib 画误差对比散点+改善幅度柱状图+方向分解图,scikit-learn 聚类找改善不明显的异常点位,networkx 建'点位-方向-改善幅度'关系网,"我开工程,"数据自包含,合成 20 个点位的标定前后坐标,下载就能跑。"
敲了行原型:
err_before = np.linalg.norm(pts[["actual_x","actual_y","actual_z"]].values -
pts[["theory_x","theory_y","theory_z"]].values, axis=1)
"完整版用 OOP 封好,"我说,"一个类管数据加载,一个类算误差,一个类做前后对比统计,一个类做显著性检验,一个类找改善异常点位,一个类建关系网,一个类出图。输出标定前后误差分布、改善幅度、异常点位清单,存 results/。"
小赵凑近看:"那以后看报告:标定前均误差 2.34mm,标定后 0.52mm,整体改善 77.8%,X 方向改善 82%,Y 方向 71%,Z 方向 79%。P12 只改善 16%,标红,建议重新采集该区域标定数据。"
"对,"我接话,"机器人标定不是'做了就行',得量化改善幅度。数字孪生里机器人模型要校准,这张误差对比表就是校准效果的验收单。"
一、实际应用场景(真实痛点)
场景设定:六轴工业机器人现场标定(四点法/激光跟踪仪),采集标定前后各 N 个示教点的理论坐标与实际坐标。调试员只能肉眼对比个别点位,无法统计整体改善幅度,也无法识别标定覆盖薄弱区域,导致"标定有效"缺乏量化证据。
现场原话(叙事化):
"不是标定没用,"小赵说,"是没法证明。我花两天标定完,工艺科问'好了多少',我说'感觉准了'。人家不信,让我拿数据。我翻出标定前后坐标表,二十个点,每个点 XYZ 三个数,我总不能让人一个个减吧?后来我拿 Excel 减了几个,发现大部分点误差从 2mm 降到 0.5mm,但有俩点只降了一点,我说不清为啥。"
"还有 XYZ 方向,有的点 X 方向改善特别明显,Z 方向几乎没变,这跟标定方法有关系——四点法对 XY 平面敏感,Z 方向补偿弱。"
核心矛盾:"标定前后坐标流水" 与 "定位误差向量计算 + 前后配对统计 + 方向分解 + 改善显著性检验 + 异常点位识别" 之间的断层。
二、痛点分析(映射到滨州职业学院《先进制造技术》课程模型)
《先进制造技术》模块 本篇痛点对应
工业机器人技术基础:机器人标定、DH参数修正、定位精度 标定前后定位误差量化对比
先进制造技术基础:精密测量与误差分析 三维空间误差向量统计
智能制造与数字孪生:机器人数字模型校准 标定效果验收的数据底座
数控加工与CAD/CAM技术:加工精度保障 机器人末端精度对标机床精度
FMS与先进生产管理:设备能力验证 标定作为设备维护标准流程的量化验收
一句话总结:我们需要一个"机器人标定前后定位误差改善幅度分析程序",用
"pandas" 加载标定数据,
"numpy" 算三维误差向量,
"scipy" 做配对 t 检验,
"scikit-learn" 聚类找改善异常点位,
"networkx" 建点位-方向关系网,实现从"感觉准了"到"量化改善幅度 + 显著性验证 + 薄弱点位定位"。
三、核心逻辑讲解(大白话)
3.1 问题本质:把机器人想成"手眼协调测试"
把机器人末端想成你的手指去点靶纸:
* 理论坐标 = 靶心位置(你应该点到的地方)
* 实际坐标 = 手指落点(实际点到的地方)
* 定位误差 = 手指离靶心多远(三维空间直线距离)
* 标定前 = 没练过的手,到处偏
* 标定后 = 练过的手,偏差小了
* 改善幅度 = (标定前误差 - 标定后误差) / 标定前误差
* 方向分解 = 偏左偏右(ΔX) vs 偏高偏低(ΔZ),看哪个方向改善最明显
* 异常点位 = 别人都进步了 80%,就它只进步 15%,说明那个区域标定没覆盖到
* 配对 t 检验 = 统计学上确认"标定确实有用",不是运气
3.2 业务逻辑 → 代码映射
加载标定前后坐标数据
│
▼ CalibDataLoader (pandas)
读取 CSV:
point_id, theory_x, theory_y, theory_z,
actual_before_x, actual_before_y, actual_before_z,
actual_after_x, actual_after_y, actual_after_z
校验坐标完整性
│
▼ ErrorCalculator (numpy)
三维误差向量:
err = √[(Ax-Tx)² + (Ay-Ty)² + (Az-Tz)²]
方向分量误差:|Ax-Tx|, |Ay-Ty|, |Az-Tz|
│
▼ ImprovementAnalyzer (pandas/numpy/scipy)
前后对比:
标定前均值/中位/最大 vs 标定后
改善幅度 = (err_before - err_after) / err_before
方向级改善:ΔX/ΔY/ΔZ 各自均值变化
scipy 配对 t 检验:标定前后误差差异显著性
│
▼ ImprovementAnomalyDetector (scikit-learn)
异常点位识别:
特征=[改善幅度, 标定后误差]
KMeans 找改善不明显的点位
│
▼ CalibGraph (networkx)
关系网:
点位-方向-改善幅度 三层图
边权=改善幅度(越小越粗=越薄弱)
│
▼ CalibVisualizer (matplotlib)
可视化:
1. 标定前后误差箱线图
2. 各点位改善幅度柱状图
3. XYZ方向误差分解对比
4. 异常点位散点(标定前误差 vs 改善幅度)
5. 点位-方向关系网
│
▼ SyntheticCalibGenerator (numpy)
合成数据:
20点位,标定前误差 1.5~3.5mm
标定后大部分降 70~85%,少量只降 10~20%
3.3 为什么需要配对 t 检验
方法 问题
看均值下降 可能是随机波动,不是标定效果
看最大误差 受极端值影响
配对 t 检验 同一点位前后配对,消除点位间差异,严格验证
3.4 分析前后对比
维度 调试员手算 本程序
误差计算 单点手减 全点位向量化
整体改善 感觉 均值+中位+最大,配对t检验
方向分解 无 XYZ 各自改善幅度
薄弱点位 靠回忆 聚类自动标红
验收报告 口头 统计+图表+显著性
四、OOP 代码实现
4.1 项目结构
robot_calib_eval/
├── robot_calib_eval/
│ ├── __init__.py
│ ├── calib_loader.py # 标定数据加载
│ ├── error_calculator.py # 三维误差计算
│ ├── improvement_analyzer.py # 前后对比统计(scipy)
│ ├── improvement_anomaly.py # 改善异常点位识别
│ ├── calib_graph.py # 点位-方向关系网
│ ├── visualizer.py # 可视化
│ └── synthetic_data.py # 合成数据
├── tests/
│ ├── __init__.py
│ └── test_calib_eval.py
├── results/
│ ├── error_box_before_after.png
│ ├── improvement_bar.png
│ ├── direction_decomp.png
│ ├── anomaly_scatter.png
│ ├── calib_graph.png
│ ├── error_detail.csv
│ ├── improvement_summary.csv
│ ├── anomaly_points.csv
│ └── calib_report.txt
└── run_calib_eval.py
4.2 核心源码
<details>
<summary></summary>
"""机器人标定数据加载器"""
import pandas as pd
from pathlib import Path
from typing import Optional, Tuple
class CalibDataLoader:
"""加载标定前后坐标数据(单文件双时段 或 两个文件)"""
def __init__(self, filepath: str = "calib_data.csv",
encoding: str = "utf-8"):
self.filepath = Path(filepath)
self.encoding = encoding
self._raw: Optional[pd.DataFrame] = None
def load(self) -> pd.DataFrame:
if not self.filepath.exists():
raise FileNotFoundError(f"文件不存在: {self.filepath}")
self._raw = pd.read_csv(self.filepath, encoding=self.encoding)
rename = {}
for tgt, al in {
"point_id": ["point_id", "点位", "id"],
"theory_x": ["theory_x", "理论X", "tx"],
"theory_y": ["theory_y", "理论Y", "ty"],
"theory_z": ["theory_z", "理论Z", "tz"],
"actual_before_x": ["actual_before_x", "标定前X", "abx"],
"actual_before_y": ["actual_before_y", "标定前Y", "aby"],
"actual_before_z": ["actual_before_z", "标定前Z", "abz"],
"actual_after_x": ["actual_after_x", "标定后X", "aax"],
"actual_after_y": ["actual_after_y", "标定后Y", "aay"],
"actual_after_z": ["actual_after_z", "标定后Z", "aaz"],
}.items():
if tgt not in self._raw.columns:
for a in al:
if a in self._raw.columns:
rename[a] = tgt
break
self._raw = self._raw.rename(columns=rename)
req = ["point_id", "theory_x", "theory_y", "theory_z",
"actual_before_x", "actual_before_y", "actual_before_z",
"actual_after_x", "actual_after_y", "actual_after_z"]
miss = [c for c in req if c not in self._raw.columns]
if miss:
raise ValueError(f"缺少必要列: {miss}")
for c in req[1:]: # 坐标列转数值
self._raw[c] = pd.to_numeric(self._raw[c], errors="coerce")
self._raw = self._raw.dropna(subset=req[1:]).reset_index(drop=True)
return self._raw.copy()
</details>
<details>
<summary></summary>
"""三维定位误差计算器 (numpy)"""
import numpy as np
import pandas as pd
from typing import Optional, Tuple
class ErrorCalculator:
"""计算标定前后各点位三维定位误差"""
def __init__(self):
pass
def calc_errors(self, df: pd.DataFrame) -> pd.DataFrame:
out = df.copy()
theory = out[["theory_x", "theory_y", "theory_z"]].values
before = out[["actual_before_x", "actual_before_y", "actual_before_z"]].values
after = out[["actual_after_x", "actual_after_y", "actual_after_z"]].values
# 欧氏距离
err_b = np.linalg.norm(before - theory, axis=1)
err_a = np.linalg.norm(after - theory, axis=1)
out["err_before_mm"] = np.round(err_b, 4)
out["err_after_mm"] = np.round(err_a, 4)
# 方向分量绝对误差
d_b = np.abs(before - theory)
d_a = np.abs(after - theory)
for i, ax in enumerate(["x", "y", "z"]):
out[f"err_before_{ax}_mm"] = np.round(d_b[:, i], 4)
out[f"err_after_{ax}_mm"] = np.round(d_a[:, i], 4)
return out
def calc_improvement(self, df: pd.DataFrame) -> pd.DataFrame:
"""计算改善幅度"""
out = df.copy()
# 改善幅度 (err_before - err_after) / err_before
imp = np.where(
out["err_before_mm"] > 0,
(out["err_before_mm"] - out["err_after_mm"]) / out["err_before_mm"],
0.0
)
out["improvement_ratio"] = np.round(imp, 4)
# 绝对改善量
out["improvement_abs_mm"] = np.round(
out["err_before_mm"] - out["err_after_mm"], 4
)
# 方向级改善
for ax in ["x", "y", "z"]:
imp_ax = np.where(
out[f"err_before_{ax}_mm"] > 0,
(out[f"err_before_{ax}_mm"] - out[f"err_after_{ax}_mm"]) /
out[f"err_before_{ax}_mm"],
0.0
)
out[f"imp_{ax}"] = np.round(imp_ax, 4)
return out
</details>
<details>
<summary></summary>
"""标定前后改善统计分析 (scipy)"""
import numpy as np
import pandas as pd
from scipy import stats
from typing import Optional, Dict
class ImprovementAnalyzer:
"""配对t检验 + 方向分解统计"""
def __init__(self, conf: float = 0.95):
self.conf = conf
def overall_stats(self, df: pd.DataFrame) -> Dict:
"""整体统计量"""
eb = df["err_before_mm"].values
ea = df["err_after_mm"].values
return {
"n_points": len(df),
"before_mean": round(float(eb.mean()), 4),
"before_median": round(float(np.median(eb)), 4),
"before_max": round(float(eb.max()), 4),
"before_std": round(float(eb.std(ddof=1)), 4),
"after_mean": round(float(ea.mean()), 4),
"after_median": round(float(np.median(ea)), 4),
"after_max": round(float(ea.max()), 4),
"after_std": round(float(ea.std(ddof=1)), 4),
"improvement_mean": round(
(eb.mean() - ea.mean()) / eb.mean() * 100, 2
) if eb.mean() > 0 else 0.0,
}
def paired_ttest(self, df: pd.DataFrame) -> Dict:
"""配对t检验: 标定前后误差差异"""
eb = df["err_before_mm"].values
ea = df["err_after_mm"].values
if len(eb) < 2:
return {"t_stat": np.nan, "p_value": np.nan}
t, p = stats.ttest_rel(eb, ea)
return {
"t_stat": round(float(t), 4),
"p_value": round(float(p), 4),
"significant": bool(p < (1 - self.conf)),
}
def direction_stats(self, df: pd.DataFrame) -> pd.DataFrame:
"""各方向改善统计"""
rows = []
for ax in ["x", "y", "z"]:
eb = df[f"err_before_{ax}_mm"].values
ea = df[f"err_after_{ax}_mm"].values
imp = df[f"imp_{ax}"].values
rows.append({
"axis": ax.upper(),
"before_mean_mm": round(float(eb.mean()), 4),
"after_mean_mm": round(float(ea.mean()), 4),
"improvement_ratio": round(float(imp.mean()), 4),
"improvement_pct": round(float(imp.mean()) * 100, 2),
})
return pd.DataFrame(rows).sort_values("improvement_pct", ascending=True).reset_index(drop=True)
def point_ranking(self, df: pd.DataFrame) -> pd.DataFrame:
"""按改善幅度排序"""
sub = df[["point_id", "err_before_mm", "err_after_mm",
"improvement_ratio", "improvement_abs_mm"]].copy()
sub = sub.sort_values("improvement_ratio").reset_index(drop=True)
return sub
</details>
<details>
<summary></summary>
"""改善异常点位识别 (scikit-learn)"""
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from typing import Optional
class ImprovementAnomalyDetector:
"""找改善不明显的点位"""
def __init__(self, n_clusters: int = 2, random_state: int = 42,
low_imp_thresh: float = 0.3):
self.n_clusters = n_clusters
self.random_state = random_state
self.low_imp_thresh = low_imp_thresh
self.scaler = StandardScaler()
def detect(self, df: pd.DataFrame) -> pd.DataFrame:
out = df.copy()
# 特征:改善幅度 + 标定后误差
X = out[["improvement_ratio", "err_after_mm"]].values
Xs = self.scaler.fit_transform(X)
k = min(self.n_clusters, len(out))
km = KMeans(n_clusters=k, random_state=self.random_state, n_init=10)
out["cluster"] = km.fit_predict(Xs)
# 改善幅度低的簇
cmean = out.groupby("cluster")["improvement_ratio"].mean()
low_cluster = cmean.idxmin()
out["cluster_is_low_imp"] = out["cluster"] == low_cluster
# 规则:改善<30% 或 标定后误差>1.5mm
out["rule_low"] = (out["improvement_ratio"] < self.low_imp_thresh) | \
(out["err_after_mm"] > 1.5)
out["is_anomaly"] = out["cluster_is_low_imp"] | out["rule_low"]
return out.sort_values("improvement_ratio").reset_index(drop=True)
def summary(self, df: pd.DataFrame) -> pd.DataFrame:
sub = df[df["is_anomaly"]]
return sub[["point_id", "err_before_mm", "err_after_mm",
"improvement_ratio", "improvement_abs_mm"]].copy()
</details>
<details>
<summary></summary>
"""点位-方向-改善幅度关系网 (networkx)"""
import networkx as nx
import pandas as pd
from typing import Optional
class CalibGraph:
"""建三层关系网"""
def __init__(self):
self.G = nx.Graph()
def build(self, df: pd.DataFrame) -> nx.Graph:
self.G.clear()
for _, r in df.iterrows():
pid = f"PT:{r['point_id']}"
self.G.add_node(pid, ntype="point")
for ax in ["X", "Y", "Z"]:
axn = f"AX:{ax}"
self.G.add_node(axn, ntype="axis")
imp_val = float(r[f"imp_{ax.lower()}"])
# 改善幅度越小(越薄弱)边越粗
w = max(0.1, (1.0 - imp_val) * 10)
self.G.add_edge(pid, axn, weight=round(w, 2),
improvement=round(imp_val, 4))
return self.G
def weak_combinations(self) -> pd.DataFrame:
"""找改善最弱的点位-方向组合"""
rows = []
for u, v, d in self.G.edges(data=True):
if self.G.nodes[u].get("ntype") == "point":
rows.append({
"point": u.split(":")[-1],
"axis": v.split(":")[-1],
"improvement": d.get("improvement", 0),
"weakness_weight": d.get("weight", 0),
})
elif self.G.nodes[v].get("ntype") == "point":
rows.append({
"point": v.split(":")[-1],
"axis": u.split(":")[-1],
"improvement": d.get("improvement", 0),
"weakness_weight": d.get("weight", 0),
})
df = pd.DataFrame(rows)
if df.empty:
return df
return df.sort_values("weakness_weight", ascending=False).reset_index(drop=True)
</details>
<details>
<summary></summary>
"""可视化 (matplotlib)"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pathlib import Path
plt.rcParams["font.sans-serif"] = ["SimHei", "DejaVu Sans"]
plt.rcParams["axes.unicode_minus"] = False
class CalibVisualizer:
def __init__(self, results_dir: str = "results"):
self.results_dir = Path(results_dir)
self.results_dir.mkdir(exist_ok=True)
def error_box_before_after(self, df):
fig, ax = plt.subplots(figsize=(8, 6))
data = [df["err_before_mm"].values, df["err_after_mm"].values]
ax.boxplot(data, labels=["标定前", "标定后"], showmeans=True)
ax.set_ylabel("定位误差 (mm)")
ax.set_title("标定前后定位误差箱线图", fontsize=14, fontweight="bold")
ax.grid(axis="y", alpha=0.3)
plt.tight_layout()
plt.savefig(self.results_dir / "error_box_before_after.png",
dpi=150, bbox_inches="tight")
plt.close()
def improvement_bar(self, rank_df):
fig, ax = plt.subplots(figsize=(14, 6))
x = range(len(rank_df))
colors = ["#E74C3C" if r < 0.3 else "#F39C12" if r < 0.6 else "#27AE60"
for r in rank_df["improvement_ratio"]]
ax.bar(x, rank_df["improvement_ratio"] * 100, color=colors)
ax.set_xticks(list(x))
ax.set_xticklabels(rank_df["point_id"], rotation=45, ha="right", fontsize=9)
ax.set_ylabel("改善幅度 (%)")
ax.set_title("各点位标定改善幅度", fontsize=14, fontweight="bold")
ax.axhline(50, ls="--", c="gray", label="50%基准线")
ax.axhline(80, ls="--", c="green", label="80%优秀线")
ax.legend()
ax.grid(axis="y", alpha=0.3)
plt.tight_layout()
plt.savefig(self.results_dir / "improvement_bar.png",
dpi=150, bbox_inches="tight")
plt.close()
def direction_decomp(self, dir_stat):
fig, ax = plt.subplots(figsize=(10, 6))
x = np.arange(len(dir_stat))
w = 0.3
ax.bar(x - w/2, dir_stat["before_mean_mm"], w,
label="标定前", color="#95A5A6")
ax.bar(x + w/2, dir_stat["after_mean_mm"], w,
label="标定后", color="#3498DB")
ax.set_xticks(x)
ax.set_xticklabels(dir_stat["axis"], fontsize=12)
ax.set_ylabel("平均误差 (mm)")
ax.set_title("XYZ方向误差分解对比", fontsize=14, fontweight="bold")
ax.legend()
ax.grid(axis="y", alpha=0.3)
# 标注改善百分比
for i, r in dir_stat.iterrows():
ax.text(i + w/2, float(r["after_mean_mm"]) + 0.05,
f"{r['improvement_pct']}%", ha="center", fontsize=9,
color="green", fontweight="bold")
plt.tight_layout()
plt.savefig(self.results_dir / "direction_decomp.png",
dpi=150, bbox_inches="tight")
plt.close()
def anomaly_scatter(self, df):
fig, ax = plt.subplots(figsize=(11, 6))
normal = df[~df["is_anomaly"]]
anom = df[df["is_anomaly"]]
ax.scatter(normal["err_before_mm"], normal["improvement_ratio"] * 100,
c="#3498DB", label="正常改善", s=40, alpha=0.7)
ax.scatter(anom["err_before_mm"], anom["improvement_ratio"] * 100,
c="#E74C3C", label="改善异常", s=80, edgecolor="k")
for _, r in anom.iterrows():
ax.annotate(r["point_id"], (r["err_before_mm"],
r["improvement_ratio"] * 100),
fontsize=8, color="red")
ax.set_xlabel("标定前误差 (mm)")
ax.set_ylabel("改善幅度 (%)")
ax.set_title("异常点位识别散点图", fontsize=14, fontweight="bold")
ax.legend()
ax.grid(alpha=0.3)
plt.tight_layout()
plt.savefig(self.results_dir / "anomaly_scatter.png",
dpi=150, bbox_inches="tight")
plt.close()
def graph_plot(self, G):
fig, ax = plt.subplots(figsize=(14, 10))
pos = nx.spring_layout(G, seed=42, k=0.8)
ncolor = []
for n, d in G.nodes(data=True):
t = d.get("ntype")
ncolor.append({"point": "#2ECC71", "axis": "#E74C3C"}.get(t, "#999"))
sizes = [300 + G.degree(n) * 40 for n in G.nodes()]
nx.draw_networkx_nodes(G, pos, node_color=ncolor,
node_size=sizes, ax=ax, alpha=0.9)
edges = list(G.edges(data=True))
ws = [d["weight"] for *_, d in edges]
nx.draw_networkx_edges(G, pos, width=ws, alpha=0.4, ax=ax,
edge_color="#E67E22")
labels = {n: n.split(":")[-1] for n, d in G.nodes(data=True)
if d.get("ntype") == "axis"}
nx.draw_networkx_labels(G, pos, labels=labels, font_size=10, ax=ax)
ax.set_title("点位-方向改善关系网\n(绿=点位 红=方向 橙线越粗=该方向改善越弱)",
fontsize=13, fontweight="bold")
ax.axis("off")
plt.tight_layout()
plt.savefig(self.results_dir / "calib_graph.png",
dpi=150, bbox_inches="tight")
plt.close()
</details>
<details>
<summary></summary>
"""合成机器人标定数据生成器"""
import numpy as np
import pandas as pd
from pathlib import Path
from typing import Optional
class SyntheticCalibGenerator:
"""
生成 20 个点位的标定前后坐标
标定前误差 1.5~3.5mm (随机偏移)
标定后大部分降 70~85%,少量只降 10~20% (薄弱区域)
"""
def __init__(self, rng: Optional[np.random.RandomState] = None):
self.rng = rng or np.random.RandomState(42)
def generate(self, output_path: str = "calib_data.csv",
n_points: int = 20) -> pd.DataFrame:
records = []
for i in range(1, n_points + 1):
pid = f"P{i:02d}"
# 理论坐标 (工作空间内随机点)
tx = float(self.rng.uniform(-800, 800))
ty = float(self.rng.uniform(-600
利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)