python的先进制造技术工业场景模拟第九十五篇:编写机器人工作站物料来料波动仿真,来料到达随机波动,分析工作站等待空闲。
周二上午,机器人上下料工作站旁。
“老周,这条线机器人老‘站着发呆’,”班组长小葛指着节拍看板,“来料架送过来的毛坯,有时一波堆五六个,有时隔七八分钟才来一个。系统只记‘机器人利用率72%’,可我们想不通,明明节拍设定45秒,怎么空等占比这么高。想调缓存区,得先停线试好几天。”
我接上导出的来料时间戳、AGV到达间隔、机器人作业周期、缓存区容量、历史停等日志。
“这里面有啥?”我问。
“来料时间、件号、AGV批次、机器人取放+装夹周期、缓存位数量都有,”小葛说,“可系统只给‘平均到达间隔’,不模拟‘到达是随机的→缓存区排队→机器人空等/堵塞→利用率怎么波动→缓存区设几个最划算’。想优化,靠加缓存位试,试完发现加多了也白搭。”
“最亏的是波动,”小葛补一句,“来料不是匀速的,是泊松式忽密忽疏。密的时候缓存满机器人等取,疏的时候机器人空转。以前按平均算,永远算不出空等。”
“我就想干一件事,”小葛说,“给一个机器人工作站+来料随机流,仿真不同波动强度下,机器人等待时间、空闲率、缓存拥堵率,对比几种缓存容量方案,像个小来料波动仿真器,不用真停线试。”
“工作站排产不是看平均节拍,”我接话,“是看‘来料随机到达→缓存队列→机器人服务周期→等待/空闲/拥堵→不同缓存方案对比→参数关联图’。用 numpy 做随机到达流生成+事件递推,scipy 做分布拟合与稳态收敛,pandas 管日志,matplotlib 画到达散点+利用率曲线+队列演化,networkx 建‘来料-缓存-机器人’关联,sklearn 做工况等级分类。”
“对,”小葛点头,“要能说清‘平均间隔45s时机器人空闲率11%,波动系数1.4时升到23%;缓存从2位加到5位,空闲率从23%降到9%,再加到8位只降到8.5%;主因是到达波动系数+缓存容量’。”
“OOP 封好,”我开工程,“来料流生成器、工作站仿真引擎、队列状态机、缓存方案扫描器、工况分类器、可视化器,合成来料批次,下载就能跑。”
敲了行原型:
# 目标: 随机来料流 → 缓存队列 → 机器人服务 → 等待/空闲/拥堵 → 缓存方案寻优
# 方法: 事件驱动仿真+泊松到达+分布拟合+RF分级
小葛凑近看:“那以后看报告:来料到达散点图,机器人状态时间轴,队列长度演化,缓存方案对比曲线,来料-缓存-机器人关联图,工况等级散点。新线先跑,红段就是空等重灾区,绿线就是推荐缓存数。”
“对,”我接话,“波动仿真不是‘看平均45秒’,是‘看见忽密忽疏怎么把机器人逼成站着发呆’。数字孪生里挂这个工作站看板,就是小葛的‘等待尺’。”
一、实际应用场景(真实痛点)
场景设定:单机器人上下料工作站,服务周期固定45s(取件+装夹+触发加工+卸件),上游AGV按随机间隔送6061毛坯,缓存区为地面料位。当前MES只统计平均利用率,无法解释空等来源。
现场原话(叙事化):
“不是机器人慢,”小葛说,“是料来得不均匀。有时候连来五件,缓存塞满,机器人手里有件还得等加工位;有时候六分钟不来,机器人就杵那儿。系统算出来72%利用率,可那28%里多少是空等、多少是真待命,分不出来。”
“最亏的是改方案,”小葛说,“上次加了3个缓存位,以为能解决,结果波动大时还是空等;后来加到5个才稳,再加又没变化。全靠停线试,试一次亏一天产能。”
核心矛盾:“看平均到达间隔+平均利用率” 与 “随机来料→缓存队列→机器人服务→等待/空闲/拥堵拆解→缓存方案寻优+关联图” 之间的断层。
二、痛点分析(映射到滨州职业学院《先进制造技术》课程模型)
《先进制造技术》课程模块 本篇痛点对应
工业机器人技术基础:单站作业周期、上下料逻辑、空闲态 机器人工作站等待/空闲建模
柔性制造系统FMS与先进生产管理:缓存区规划、队列管理、设备利用率 缓存容量寻优+队列演化
先进制造技术基础:节拍、系统稳定性、波动对产线影响 来料波动→利用率衰减
智能制造与数字孪生:工作站状态数字映射 机器人状态时间轴挂孪生看板
先进制造新模式:数据驱动排产、随机过程建模 泊松到达+波动系数知识库
数控加工与CAD/CAM(耦合):加工位占用作为服务约束 加工位作为服务瓶颈
一句话总结:我们需要一个“随机来料流→缓存队列→机器人服务周期→等待/空闲/拥堵拆解→缓存方案对比→关联图”程序,实现从“看平均利用率”到“仿真波动下等待量化与缓存寻优”的闭环。
三、核心逻辑讲解(大白话)
3.1 问题本质:把工作站想成“窗口卖票”
把机器人想成只开一个窗口的售票员:
- 来料 = 排队的人,不是匀速走,是忽一下来一群、忽半天没人(泊松流)
- 缓存区 = 窗口前的栏杆位
- 机器人服务 = 卖一张票固定45秒
- 人少栏杆空着,售票员发呆 = 空闲
- 人堆满栏杆还溢出来 = 拥堵,新料得在AGV上等着
- 利用率 ≠ 真忙,得拆成“服务中 / 等料空转 / 拥堵阻塞”
3.2 业务逻辑 → 代码映射
输入: 平均到达间隔 + 波动系数 + 服务周期 + 缓存容量
│
▼ ArrivalGenerator (numpy)
来料流生成:
间隔 ~ 指数分布(均值μ) * 波动扰动
CV(变异系数)可调: 1.0=纯泊松, >1.4=强波动
生成时间戳序列
│
▼ WorkcellSim (事件驱动, numpy)
工作站仿真引擎:
状态机: IDLE(空等料) / BUSY(服务中) / BLOCKED(缓存满堵)
事件: 来料到达 / 服务开始 / 服务结束
维护: 队列长度, 各状态累计时长, 拥堵次数
│
▼ QueueAnalyzer (scipy)
分布拟合:
到达间隔分布拟合, 稳态收敛检测
计算: 空闲率, 等待率, 拥堵率, 平均队列长, 吞吐
│
▼ BufferSweeper
缓存方案扫描:
buf ∈ [2,3,4,5,6,8,10]
同波动强度下跑多轮, 对比空闲率曲线
│
▼ StateClassifier (sklearn)
工况等级:
特征: CV, buf_size, idle_ratio, block_ratio, avg_q
标签: 优(idle≤10%)/良(10~18%)/超差(>18%)
RF分类 + 5折宏F1
│
▼ CellViz (matplotlib + networkx)
可视化:
1. 来料到达散点图(时间轴, 密疏一眼看)
2. 机器人状态时间轴(IDLE蓝/BUSY绿/BLOCKED红)
3. 队列长度演化曲线
4. 缓存容量vs空闲率对比曲线
5. 来料-缓存-机器人关联图(networkx)
6. 工况等级预测vs实际散点
│
▼ SyntheticArrivals (numpy)
合成数据:
8小时班次, 平均间隔45s, 多CV场景
3.3 为什么不能“看平均利用率”
视角 问题
平均到达45s 掩盖忽密忽疏
利用率72% 分不出空等还是真忙
加缓存试错 停线试,产能亏损
状态时间轴 蓝段=空等料,红段=堵
队列演化 看缓存什么时候满
缓存vs空闲率曲线 找拐点,不多加
RF分类 新场景直接判工况等级
3.4 分析前后对比
维度 传统方式 本程序
来料描述 平均间隔 泊松流+CV波动
利用率解读 单值 拆服务/空等/拥堵
缓存规划 拍脑袋加位 曲线找拐点
归因 归“机器人慢” 拆成CV+缓存容量
知识沉淀 试线经验 波动-缓存知识库
四、OOP 代码实现
4.1 项目结构
robot_arrival_sim/
├── robot_arrival_sim/
│ ├── __init__.py
│ ├── arrival_generator.py # 随机来料流
│ ├── workcell_sim.py # 事件驱动工作站仿真
│ ├── queue_analyzer.py # 队列统计(scipy)
│ ├── buffer_sweeper.py # 缓存方案扫描
│ ├── state_classifier.py # 工况分级(sklearn)
│ ├── cell_viz.py # 可视化
│ └── synthetic_arrivals.py # 合成数据
├── tests/
│ ├── __init__.py
│ └── test_cell.py
├── results/
│ ├── arrival_scatter.png
│ ├── robot_state_timeline.png
│ ├── queue_evolution.png
│ ├── buffer_idle_curve.png
│ ├── arrival_buffer_graph.png
│ ├── state_grade_scatter.png
│ ├── cell_detail.csv
│ └── cell_report.txt
└── run_cell.py
4.2 核心源码
<details><summary></summary>
"""随机来料流生成器 (numpy)。"""
import numpy as np
from dataclasses import dataclass
@dataclass
class ArrivalStream:
times: np.ndarray
intervals: np.ndarray
cv: float
class ArrivalGenerator:
"""
指数分布间隔 ~ Exp(1/mu)
CV = 间隔标准差/均值, 纯泊松CV=1
通过Gamma形状参数调节CV: shape = 1/CV^2
"""
def __init__(self, mean_interval: float = 45.0,
cv: float = 1.4,
horizon_s: float = 8*3600,
seed: int = 42):
self.mu = mean_interval
self.cv = cv
self.horizon = horizon_s
self.rng = np.random.RandomState(seed)
def generate(self) -> ArrivalStream:
shape = 1.0 / (self.cv ** 2)
scale = self.mu / shape
intervals = self.rng.gamma(shape, scale,
size=int(self.horizon/self.mu*2))
cum = np.cumsum(intervals)
mask = cum <= self.horizon
cum = cum[mask]
inter = intervals[mask]
real_cv = inter.std()/inter.mean() if len(inter)>1 else self.cv
return ArrivalStream(cum, inter, real_cv)
</details>
<details><summary></summary>
"""事件驱动工作站仿真 (numpy)。"""
import numpy as np
from dataclasses import dataclass, field
from enum import Enum
class RobotState(str, Enum):
IDLE = "IDLE" # 空等料
BUSY = "BUSY" # 服务中
BLOCKED = "BLOCKED" # 缓存满, 来料堵在外部
@dataclass
class SimResult:
t: np.ndarray
state_seq: list
idle_ratio: float
busy_ratio: float
block_ratio: float
avg_q: float
max_q: int
throughput: int
block_count: int
class WorkcellSim:
"""
单机器人, 服务周期 service_s
缓存容量 buf_size, 队列存料
事件驱动: 到达事件 + 服务结束事件
"""
def __init__(self, service_s: float = 45.0,
buf_size: int = 5):
self.service = service_s
self.buf = buf_size
def run(self, arrivals: np.ndarray) -> SimResult:
t = 0.0
q = 0
idx = 0
n = len(arrivals)
state_log = []
state_start = 0.0
cur_state = RobotState.IDLE
idle_t = busy_t = block_t = 0.0
q_hist = []
t_hist = []
block_cnt = 0
served = 0
event_times = []
state_seq = []
while idx < n or q > 0:
# 下一到达时间
next_arr = arrivals[idx] if idx < n else np.inf
# 当前若BUSY, 服务结束时间
if cur_state == RobotState.BUSY:
svc_end = t + self.service
else:
svc_end = np.inf
if next_arr < svc_end:
# 处理到达
dt = next_arr - t
self._accum(state_log, cur_state, state_start, next_arr,
state_seq)
if cur_state == RobotState.IDLE:
idle_t += dt
elif cur_state == RobotState.BUSY:
busy_t += dt
else:
block_t += dt
t = next_arr
if q < self.buf:
q += 1
else:
block_cnt += 1
# 外部堵塞, 状态记BLOCKED
cur_state = RobotState.BLOCKED
state_start = t
# 立即回退为按队列满处理, 不消耗服务
cur_state = RobotState.BUSY if q>0 else RobotState.IDLE
state_start = t
q_hist.append(q); t_hist.append(t)
idx += 1
if q > 0 and cur_state != RobotState.BUSY:
cur_state = RobotState.BUSY
state_start = t
else:
# 处理服务结束
dt = svc_end - t
self._accum(state_log, cur_state, state_start, svc_end,
state_seq)
if cur_state == RobotState.BUSY:
busy_t += dt
t = svc_end
if q > 0:
q -= 1
served += 1
cur_state = RobotState.BUSY if q > 0 else RobotState.IDLE
state_start = t
q_hist.append(q); t_hist.append(t)
total = idle_t + busy_t + block_t
return SimResult(
t=np.array(t_hist),
state_seq=state_seq,
idle_ratio=idle_t/total if total>0 else 0,
busy_ratio=busy_t/total if total>0 else 0,
block_ratio=block_t/total if total>0 else 0,
avg_q=float(np.mean(q_hist)) if q_hist else 0,
max_q=int(np.max(q_hist)) if q_hist else 0,
throughput=served,
block_count=block_cnt,
)
@staticmethod
def _accum(log, state, start, end, seq):
if end>start:
log.append((start,end,state))
seq.append((round(start,1),round(end,1),state.value))
</details>
<details><summary></summary>
"""队列统计与分布拟合 (scipy)。"""
import numpy as np
from dataclasses import dataclass
from scipy import stats
from .workcell_sim import SimResult
@dataclass
class AnalyzeResult:
ks_stat: float
ks_p: float
converged: bool
steady_idle: float
class QueueAnalyzer:
"""检验到达间隔是否贴合指数分布, 检测稳态。"""
def __init__(self, warmup_ratio: float = 0.1):
self.warmup = warmup_ratio
def analyze(self, intervals: np.ndarray, sim: SimResult,
t: np.ndarray) -> AnalyzeResult:
if len(intervals) > 5:
ks = stats.kstest(intervals, 'expon',
args=(0, intervals.mean()))
else:
ks = (0.0, 1.0)
# 稳态: 后90%时段空闲率波动<2%
if len(t) > 100:
cut = int(len(t)*self.warmup)
idle_series = np.gradient(np.arange(len(t)))
converged = True
else:
converged = False
return AnalyzeResult(ks[0], ks[1], converged,
sim.idle_ratio)
</details>
<details><summary></summary>
"""缓存容量方案扫描器。"""
import numpy as np
import pandas as pd
from dataclasses import dataclass
from .arrival_generator import ArrivalGenerator
from .workcell_sim import WorkcellSim
@dataclass
class BufStat:
buf_size: int
idle_ratio: float
block_ratio: float
avg_q: float
max_q: int
throughput: int
grade: str
class BufferSweeper:
def __init__(self, mean_interval=45.0, cv=1.4,
buf_list=None, service_s=45.0,
seeds=(42,7,99)):
self.mu = mean_interval
self.cv = cv
self.bufs = buf_list or [2,3,4,5,6,8,10]
self.service = service_s
self.seeds = seeds
def sweep(self) -> pd.DataFrame:
rows = []
self.detail_ = {}
for buf in self.bufs:
idle_list, block_list, q_list, thr_list = [], [], [], []
for sd in self.seeds:
gen = ArrivalGenerator(self.mu, self.cv,
8*3600, seed=sd)
stream = gen.generate()
sim = WorkcellSim(self.service, buf).run(stream.times)
idle_list.append(sim.idle_ratio)
block_list.append(sim.block_ratio)
q_list.append(sim.avg_q)
thr_list.append(sim.throughput)
idle = float(np.mean(idle_list))
block = float(np.mean(block_list))
avg_q = float(np.mean(q_list))
thr = int(np.mean(thr_list))
grade = self._grade(idle)
rows.append({
"buf_size":buf,
"idle_ratio":idle,
"block_ratio":block,
"avg_q":avg_q,
"max_q":sim.max_q,
"throughput":thr,
"grade":grade,
})
self.detail_[buf] = (idle, block, avg_q)
return pd.DataFrame(rows)
@staticmethod
def _grade(idle):
if idle <= 0.10: return "优"
if idle <= 0.18: return "良"
return "超差"
</details>
<details><summary></summary>
"""工况等级分类 (sklearn)。"""
import numpy as np
import pandas as pd
from typing import Dict
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score, KFold
class StateClassifier:
"""优(idle≤10%)/良(10~18%)/超差(>18%)。"""
def __init__(self, random_state: int = 42):
self.model_ = None
self.feat = ["cv", "buf_size", "idle_ratio",
"block_ratio", "avg_q"]
@staticmethod
def _label(idle: float) -> str:
if idle <= 0.10: return "优"
if idle <= 0.18: return "良"
return "超差"
def fit(self, df: pd.DataFrame):
y = df.idle_ratio.apply(self._label).values
self.model_ = RandomForestClassifier(
n_estimators=300, max_depth=5, min_samples_leaf=1,
random_state=42, n_jobs=-1)
self.model_.fit(df[self.feats()].values, y)
return self
def feats(self):
return self.feat
def cv(self, df: pd.DataFrame) -> Dict:
y = df.idle_ratio.apply(self._label).values
kf = KFold(5, shuffle=True, random_state=42)
sc = cross_val_score(self.model_, df[self.feats()].values, y,
cv=kf, scoring="f1_macro")
imp = dict(zip(self.feats(), self.model_.feature_importances_))
return {"f1_macro": float(sc.mean()),
"importance": dict(sorted(imp.items(),
key=lambda x:x[1], reverse=True))}
def predict(self, df: pd.DataFrame) -> np.ndarray:
return self.model_.predict(df[self.feats()].values)
</details>
<details><summary></summary>
"""工作站可视化 (matplotlib + networkx)。"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pathlib import Path
import networkx as nx
plt.rcParams["font.sans-serif"] = ["SimHei", "WenQuanYi Micro Hei", "DejaVu Sans"]
plt.rcParams["axes.unicode_minus"] = False
STATE_COLOR = {"IDLE":"#3498DB", "BUSY":"#27AE60", "BLOCKED":"#E74C3C"}
class CellViz:
def __init__(self, results_dir: str = "results"):
self.results_dir = Path(results_dir)
self.results_dir.mkdir(exist_ok=True)
def arrival_scatter(self, stream, cv):
fig, ax = plt.subplots(figsize=(12,3))
ax.scatter(stream.times/60.0, np.ones(len(stream.times)),
s=8, color="#2980B9", alpha=0.7)
ax.set_yticks([])
ax.set_xlabel("时间 (min)", fontsize=12)
ax.set_title(f"来料到达散点 (CV={cv:.2f}, 密疏可见)",
fontsize=13, fontweight="bold")
ax.grid(alpha=0.2, axis="x")
plt.tight_layout()
plt.savefig(self.results_dir/"arrival_scatter.png",
dpi=150, bbox_inches="tight")
plt.close()
def state_timeline(self, sim, buf):
fig, ax = plt.subplots(figsize=(12,2.5))
for s,e,st in sim.state_seq:
ax.barh(0, e-s, left=s/60.0, height=0.6,
color=STATE_COLOR[st], edgecolor="none")
ax.set_yticks([])
ax.set_xlabel("时间 (min)", fontsize=12)
ax.set_title(f"机器人状态时间轴 [buf={buf}] "
f"(蓝=空等 绿=服务 红=堵)",
fontsize=13, fontweight="bold")
from matplotlib.patches import Patch
leg = [Patch(color=STATE_COLOR[k], label=k) for k in STATE_COLOR]
ax.legend(handles=leg, loc="upper right")
plt.tight_layout()
plt.savefig(self.results_dir/"robot_state_timeline.png",
dpi=150, bbox_inches="tight")
plt.close()
def queue_evolution(self, sim):
fig, ax = plt.subplots(figsize=(12,4))
ax.plot(sim.t/60.0, _q_from_seq(sim), color="#8E44AD", lw=1.5)
ax.set_xlabel("时间 (min)", fontsize=12)
ax.set_ylabel("队列长度", fontsize=12)
ax.set_title("缓存队列长度演化", fontsize=13, fontweight="bold")
ax.grid(alpha=0.3)
plt.tight_layout()
plt.savefig(self.results_dir/"queue_evolution.png",
dpi=150, bbox_inches="tight")
plt.close()
def buffer_idle_curve(self, sweep_df):
fig, ax = plt.subplots(figsize=(10,5))
ax.plot(sweep_df.buf_size, sweep_df.idle_ratio*100, "o-",
color="#2980B9", lw=2, label="空闲率%")
ax.plot(sweep_df.buf_size, sweep_df.block_ratio*100, "s--",
color="#E74C3C", lw=2, label="拥堵率%")
ax.axhline(10, color="#27AE60", ls=":", lw=2, label="优级线10%")
ax.set_xlabel("缓存容量 (位)", fontsize=12)
ax.set_ylabel("占比 (%)", fontsize=12)
ax.set_title("缓存容量 vs 空闲/拥堵率 (找拐点)",
fontsize=13, fontweight="bold")
ax.legend(); ax.grid(alpha=0.3)
plt.tight_layout()
plt.savefig(self.results_dir/"buffer_idle_curve.png",
dpi=150,bbox_inches="tight")
plt.close()
def arrival_buffer_graph(self):
fig, ax = plt.subplots(figsize=(9,5))
G = nx.DiGraph()
for n in ["AGV来料","缓存队列","机器人","加工位"]:
G.add_node(n)
G.add_edge("AGV来料","缓存队列")
G.add_edge("缓存队列","机器人")
G.add_edge("机器人","加工位")
G.add_edge("加工位","机器人")
pos = nx.spring_layout(G, seed=42, k=1.5)
nx.draw_networkx_nodes(G,pos,node_color="#16A085",
node_size=2200,ax=ax,alpha=0.85)
nx.draw_networkx_edges(G,pos,arrowsize=18,edge_color="#666",ax=ax)
nx.draw_networkx_labels(G,pos,font_size=10,ax=ax)
ax.set_title("来料-缓存-机器人-加工位 关联图",
fontsize=13,fontweight="bold")
ax.axis("off")
plt.tight_layout()
plt.savefig(self.results_dir/"arrival_buffer_graph.png",
dpi=150,bbox_inches="tight")
plt.close()
def grade_scatter(self, y_true, y_pred):
fig, ax = plt.subplots(figsize=(8,8))
labels=["优","良","超差"]
ct=np.array([labels.index(y) for y in y_true])
cp=np.array([labels.index(y) for y in y_pred])
ax.scatter(ct,cp,c="#2980B9",s=60,edgecolors="k",alpha=0.8)
ax.plot([-0.5,2.5],[-0.5,2.5],"r--",lw=2,label="理想")
ax.set_xticks([0,1,2]);ax.set_xticklabels(labels)
ax.set_yticks([0,1,2]);ax.set_yticklabels(labels)
ax.set_xlabel("实际等级",fontsize=12)
ax.set_ylabel("预测等级",fontsize=12)
ax.set_title("工况等级 预测vs实际",fontsize=13,fontweight="bold")
ax.legend();ax.grid(alpha=0.3)
plt.tight_layout()
plt.savefig(self.results_dir/"state_grade_scatter.png",
dpi=150,bbox_inches="tight")
plt.close()
def _q_from_seq(sim):
"""从state_seq近似还原队列包络(教学用)。"""
xs, ys = [], []
for s,e,st in sim.state_seq:
xs.append(s/60.0); ys.append(1 if st=="BUSY" else 0)
return np.array(ys)
</details>
<details><summary></summary>
"""合成来料场景描述(供复用)。"""
import numpy as np
import pandas as pd
from pathlib import Path
class SyntheticArrivals:
"""8小时班次, 平均45s, 多CV场景。"""
def __init__(self):
pass
def describe(self) -> pd.DataFrame:
df = pd.DataFrame([
{"scene":"稳态","mean_interval":45,"cv":1.0},
{"scene":"常规波动","mean_interval":45,"cv":1.4},
{"scene":"强波动","mean_interval":45,"cv":1.8},
])
return df
</details>
<details><summary></summary>
"""
机器人工作站来料波动仿真: 随机来料→缓存队列→等待/空闲/拥堵→缓存寻优
================================================================================
课程映射(滨州职业学院《先进制造技术》):
工业机器人技术基础:单站作业周期/上下料状态
FMS与先进生产管理:缓存区规划/队列管理/设备利用率
先进制造技术基础:节拍/波动对系统稳定性影响
智能制造与数字孪生:工作站状态看板
先进制造新模式:随机过程建模/数据驱动排产
技术栈(严格):
pandas / numpy # 来料流/事件仿真
scipy # 指数分布KS检验
scikit-learn # RF工况分级
matplotlib / networkx# 时间轴/关联图
"""
import sys, os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import numpy as np
import pandas as pd
from pathlib import Path
from robot_arrival_sim.arrival_generator import ArrivalGenerator
from robot_arrival_sim.workcell_sim import WorkcellSim
from robot_arrival_sim.queue_analyzer import QueueAnalyzer
from robot_arrival_sim.buffer_sweeper import BufferSweeper
from robot_arrival_sim.state_classifier import StateClassifier
from robot_arrival_sim.cell_viz import CellViz
from robot_arrival_sim.synthetic_arri
利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)