Digital Twin task logs for Collective Robotic Construction (CRC) — ROB|ARCH 2024
收藏DataCite Commons2026-01-14 更新2026-05-07 收录
下载链接:
https://darus.uni-stuttgart.de/citation?persistentId=doi:10.18419/DARUS-5612
下载链接
链接失效反馈官方服务:
资源简介:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Digital Twin task logs for Collective Robotic Construction (CRC) — ROB|ARCH 2024</title>
<style>
:root{
--bg:#ffffff; --fg:#111827; --muted:#6b7280; --border:#e5e7eb;
--codebg:#0b1020; --codefg:#e5e7eb; --link:#2563eb;
}
html,body{background:var(--bg); color:var(--fg); margin:0; font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif; line-height:1.6;}
main{max-width:980px; margin:0 auto; padding:32px 20px 64px;}
h1,h2,h3{line-height:1.25; margin:1.2em 0 .5em;}
h1{font-size:2rem; margin-top:0;}
h2{font-size:1.35rem; border-top:1px solid var(--border); padding-top:1.1rem;}
h3{font-size:1.1rem;}
p{margin:.75em 0;}
ul,ol{padding-left:1.3em;}
code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; font-size:.95em;}
pre{background:var(--codebg); color:var(--codefg); padding:14px 16px; border-radius:10px; overflow:auto; border:1px solid rgba(255,255,255,.08);}
pre code{color:inherit;}
a{color:var(--link); text-decoration:none;}
a:hover{text-decoration:underline;}
hr{border:0; border-top:1px solid var(--border); margin:1.6em 0;}
table{width:100%; border-collapse:collapse; margin:1em 0; font-size:.95rem;}
th,td{border:1px solid var(--border); padding:10px 10px; vertical-align:top;}
th{background:#f9fafb; text-align:left;}
.muted{color:var(--muted);}
</style>
</head>
<body>
<main>
<h1>Digital Twin task logs for Collective Robotic Construction (CRC) — ROB|ARCH 2024</h1>
<h2>Overview</h2>
<p>
This repository contains a dataset of <strong>Digital Twin (DT) task logs</strong> from a
<strong>Collective Robotic Construction (CRC)</strong> workshop held at <strong>ROB|ARCH 2024</strong>.
Over three days, 14 participants programmed eight low-cost mobile robots (<strong>RADr</strong>) to develop
and test <em>decentralised</em> construction behaviours, while a <strong>Vicon motion tracking system</strong>
provided global state feedback.
</p>
<p>The dataset captures the DT’s <strong>task-level interaction</strong> with:</p>
<ul>
<li><strong>8 RADr robots</strong> (mobile, magnetic gripper, onboard sensors)</li>
<li><strong>Vicon</strong> (external tracking of robot + material poses)</li>
<li><strong>Digital material modules</strong> (passive tracked objects; labelled <code>DM0…</code>)</li>
</ul>
<p>
Each experimental run is recorded as a JSON array of <em>task records</em> (e.g., <code>Move</code>,
<code>Grip</code>, <code>Read</code>) with timestamps, task parameters, and the corresponding responses
from the physical actors.
</p>
<h2>Case study context (CRC)</h2>
<ul>
<li>Workspace: ~4.6 × 5.8 m floor divided into a 4 × 5 grid.</li>
<li>Tracking: Vicon motion capture (overhead coverage).</li>
<li>Robots: 8 × RADr (2-wheel drive, magnetic gripper, onboard proximity/boundary sensors).</li>
<li>Materials: passive “digital material” modules with retroreflective markers (tracked by Vicon).</li>
<li>
Execution mode: <strong>Adaptive multi-actor execution</strong> (robots act in parallel; robots can be
inserted/removed/reprogrammed during a run; DT maintains shared situational awareness).
</li>
</ul>
<p>The DT architecture instantiated two principal task families:</p>
<ul>
<li><strong>RADr tasks:</strong> <code>Move</code>, <code>Grip</code></li>
<li><strong>Vicon tasks:</strong> <code>Read</code> (a.k.a. <code>ReadState</code> snapshots)</li>
</ul>
<h2>Repository structure</h2>
<pre><code>.
├── Data/
│ ├── Run-1.json
│ ├── Run-2.json
│ ├── ...
│ └── Run-12.json
├── Figures/
│ ├── Tasks and durations per CRC run.png
│ ├── Average task rate per RADr robot.png
│ └── Per RADr control loop times.png
├── Analysis.py
└── Replay_Run.gh
</code></pre>
<h3>What each top-level item is</h3>
<ul>
<li><code>Data/Run-*.json</code>: <strong>Primary dataset.</strong> One JSON file per CRC run (job).</li>
<li><code>Figures/</code>: Example plots generated from <code>Analysis.py</code> (included for convenience).</li>
<li><code>Analysis.py</code>: Reference analysis script that loads the runs and reproduces the included plots.</li>
<li>
<code>Replay_Run.gh</code>: Grasshopper definition (Rhino/Grasshopper) for replaying/visualising a run
(see “Replay” section below).
</li>
</ul>
<h2>Runs included</h2>
<p>
The dataset contains <strong>12 runs</strong> (<code>Run-1</code> … <code>Run-12</code>).
Each run is a task log containing a mixture of:
</p>
<ul>
<li>Vicon <code>Read</code> snapshots (typically ~1 Hz)</li>
<li>RADr <code>Move</code> tasks (motor commands)</li>
<li>RADr <code>Grip</code> tasks (motor commands + gripper toggle)</li>
</ul>
<p><strong>Overall totals (all runs combined):</strong></p>
<ul>
<li>Total task records: <strong>22,571</strong></li>
<li>Vicon <code>Read</code>: <strong>12,688</strong></li>
<li>RADr <code>Move</code>: <strong>8,080</strong></li>
<li>RADr <code>Grip</code>: <strong>1,234</strong></li>
<li>Mean run duration: <strong>18.43 min</strong> (range: <strong>8.98–40.72 min</strong>)</li>
</ul>
<h2>Data format</h2>
<p>Each <code>Data/Run-*.json</code> file is a <strong>JSON array</strong>:</p>
<pre><code class="language-json">[
{ "task_id": "...", "task_type": "Read", "main_actor": "Vicon", ... },
{ "task_id": "...", "task_type": "Move", "main_actor": "RADr_3", ... },
...
]</code></pre>
<h3>Task record schema (common fields)</h3>
<p>Task Data Schema that includes the following fields:</p>
<ul>
<li><strong>task_id:</strong> A unique identifier for the task record (UUID).</li>
<li><strong>name:</strong> A human-readable task name (e.g., <code>"Wander"</code>, <code>"Pick"</code>, <code>"Vicon_ReadValues"</code>).</li>
<li><strong>task_type:</strong> The task category/type (one of <code>Read</code>, <code>Move</code>, <code>Grip</code>; plus one <code>Capture</code> placeholder).</li>
<li><strong>main_actor:</strong> The physical actor that executed the task (e.g., <code>Vicon</code>, <code>RADr_0…RADr_7</code>).</li>
<li><strong>description:</strong> Optional description text for the task.</li>
<li><strong>message:</strong> A log message associated with the task.</li>
<li><strong>element_id:</strong> Optional list of related design element references (empty in these runs).</li>
<li><strong>job:</strong> The run identifier associated with this record (e.g., <code>"Run-4"</code>).</li>
<li><strong>level:</strong> Process hierarchy level (mostly <code>0</code> in these logs).</li>
<li><strong>task_index:</strong> Task order/index value (<code>null</code> in these logs).</li>
<li><strong>actors_data:</strong> Task input parameters grouped per actor (nested details omitted).</li>
<li><strong>start_time:</strong> Task start timestamp (ISO 8601 string) or <code>null</code>.</li>
<li><strong>end_time:</strong> Task end timestamp (ISO 8601 string) or <code>null</code>.</li>
<li><strong>progress:</strong> Task state indicator (observed values: <code>0</code>, <code>1</code>, <code>2</code>).</li>
<li><strong>response:</strong> Task output/response payload for the actor (may be <code>null</code>; nested details omitted).</li>
<li><strong>project:</strong> Project identifier (e.g., <code>"col_robots"</code>).</li>
</ul>
<h2>Task types and their data structures</h2>
<h3>1) Vicon — <code>Read</code></h3>
<p><strong>Purpose:</strong> request a global environment snapshot from Vicon.</p>
<p>Typical fields:</p>
<ul>
<li><code>main_actor</code>: <code>"Vicon"</code></li>
<li><code>task_type</code>: <code>"Read"</code></li>
<li><code>actors_data</code>: <code>{"Vicon": {"ReadData": "true"}}</code></li>
<li><code>response</code>: <code>{"Vicon": "&lt;JSON string&gt;"}</code></li>
</ul>
<h3>Vicon response payload structure</h3>
<p>After <code>json.loads(record["response"]["Vicon"])</code>, you obtain a dictionary:</p>
<pre><code class="language-python">{
"RADr_0": [ [ [x,y,z], flag ], [ [qx,qy,qz,qw], flag ] ],
"RADr_1": [ ... ],
...
"DM0": [ [ [x,y,z], flag ], [ [qx,qy,qz,qw], flag ] ],
...
}</code></pre>
<p>Where:</p>
<ul>
<li><code>x,y,z</code> are positions in the Vicon world frame (values suggest <strong>millimetres</strong>, z ~ 60–130 mm for floor objects).</li>
<li><code>qx,qy,qz,qw</code> are a quaternion orientation.</li>
<li><code>flag</code> is a Boolean that indicate measurement validity/occlusion (in these logs it is typically <code>false</code>).</li>
</ul>
<p>Entity keys include:</p>
<ul>
<li>Robots: <code>RADr_0</code> … <code>RADr_7</code></li>
<li>Digital materials: <code>DM0</code> … <code>DM24</code></li>
</ul>
<h3>2) RADr — <code>Move</code> and <code>Grip</code></h3>
<p>
RADr tasks control an individual two-wheeled robot (<code>RADr_i</code>). In this dataset there are two closely
related task types:
</p>
<ul>
<li><strong><code>Move</code></strong>: send a wheel-motor command sequence.</li>
<li><strong><code>Grip</code></strong>: send a wheel-motor command sequence <strong>and</strong> toggle the magnetic gripper.</li>
</ul>
<p>Typical fields:</p>
<ul>
<li><code>main_actor</code>: <code>"RADr_6"</code> (or any <code>RADr_i</code>)</li>
<li><code>task_type</code>: <code>"Move"</code> or <code>"Grip"</code></li>
<li><code>actors_data["RADr_i"]["move_vectors"]</code>: a <em>string</em> representing a list of 2D wheel-force vectors, one per control step</li>
<li><code>actors_data["RADr_i"]["gripper"]</code> (<em>only for</em> <code>Grip</code>): <code>"True"</code> / <code>"False"</code> (stored as a string)</li>
</ul>
<p>Example <code>actors_data</code> snippets:</p>
<pre><code class="language-json">// Move
"actors_data": {
"RADr_6": {
"move_vectors": "[[-0.1, 0.0], [0.0, 0.65], [0.0, 0.8], [0.0, 1.0]]"
}
}</code></pre>
<pre><code class="language-json">// Grip
"actors_data": {
"RADr_6": {
"gripper": "True",
"move_vectors": "[[0.0, 0.5], [0.0, 1.0], [0.0, 1.0]]"
}
}</code></pre>
<h3>RADr response payload (common to <code>Move</code> and <code>Grip</code>)</h3>
<p>
<code>response</code> typically contains a per-robot entry whose value is a JSON <em>string</em> that must be parsed
with <code>json.loads(...)</code>. After parsing, the response provides an updated local state from onboard sensors:
</p>
<table>
<thead>
<tr><th>Key</th><th>Type</th><th>Meaning</th></tr>
</thead>
<tbody>
<tr><td><code>Material_Sensor</code></td><td>bool</td><td>Whether a material module is detected nearby.</td></tr>
<tr><td><code>Gripper</code></td><td>bool</td><td>Current magnetic gripper state.</td></tr>
<tr><td><code>Robot_Sensor</code></td><td>int</td><td>Robot proximity sensor indicator (values observed: -1, 0, …).</td></tr>
<tr><td><code>Boundary_Sensor</code></td><td>bool</td><td>Boundary detection (e.g., leaving the work area).</td></tr>
<tr><td><code>Counter</code></td><td>int</td><td>A robot-side counter / tick value (useful for debugging timing).</td></tr>
</tbody>
</table>
<h2>Derived metrics (as used in <code>Analysis.py</code>)</h2>
<p>The included analysis script derives two useful “DT performance” proxies from the task logs:</p>
<h3>Task rate per robot</h3>
<p>For each robot and run:</p>
<ul>
<li><code>task_rate = (# Move + Grip tasks) / (robot active time)</code></li>
</ul>
<p>
Active time is computed from the robot’s first task start to its last task end within a run.
</p>
<p>Average task-rate summary (mean ± std across runs):</p>
<p>Overall mean across robots (mean of robot means): <strong>8.44 tasks/min</strong>.</p>
<h3>Approximate per-robot control-loop time</h3>
<p>For each robot, an “ABM-like loop time” is approximated as:</p>
<p><code>loop_time_s = start_time(next task) - end_time(current task)</code></p>
<p>This captures the combined effects of:</p>
<ul>
<li>participant logic / ABM compute time,</li>
<li>DT engine scheduling,</li>
<li>communication latency,</li>
<li>and any short pauses between tasks.</li>
</ul>
<p>Overall mean (after outlier removal): <strong>0.66 s</strong>.</p>
<h2>Usage</h2>
<h3>1) Load the dataset in Python</h3>
<pre><code class="language-python">import json
import pandas as pd
with open("Data/Run-1.json", "r") as f:
tasks = json.load(f)
df = pd.DataFrame(tasks)
</code></pre>
<h3>2) Reproduce the included figures</h3>
<p>Install dependencies:</p>
<pre><code class="language-bash">pip install numpy pandas matplotlib</code></pre>
<p>Run:</p>
<pre><code class="language-bash">python Analysis.py</code></pre>
<p>The script reads all files in <code>Data/</code> and writes plots to <code>Figures/</code>.</p>
<h3>3) Replay in Grasshopper (Rhino)</h3>
<p>
<code>Replay_Run.gh</code> is a Grasshopper definition intended to visualise a run by reading Vicon snapshots
from the task logs and animating robot/material poses. Open it in Rhino/Grasshopper and ensure the
<code>Data/</code> folder path is correctly set inside the definition.
</p>
<p class="muted">
(<em>Exact inputs/parameters depend on your Grasshopper environment; this repository does not include a
<code>*.ghx</code> parameter manifest.</em>)
</p>
<h2>Notes and known quirks</h2>
<ul>
<li><strong>Timestamps:</strong> <code>start_time</code>/<code>end_time</code> are ISO 8601 strings; a small fraction of records may contain <code>null</code>.</li>
<li><strong>Units:</strong> Vicon positions are presented in <strong>millimetres</strong> in a fixed world frame (based on magnitude vs. the physical workspace size).</li>
</ul>
</main>
</body>
</html>
提供机构:
DaRUS
创建时间:
2026-01-14



