File size: 6,363 Bytes
53a2e9c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | import { useState } from "react";
import { Clock3, Layers3 } from "lucide-react";
const types = [
"Subtasks",
"Plans",
"Memory",
"Task rephrasings",
"Interjections & speech",
"Visual questions",
];
const phases = [
{
title: "Pick up a cup and place it on a tray",
duration: "8.0 s",
rows: [
["0.0–1.4 s", "Reach the right gripper toward the cup", 1.4],
["1.4–2.5 s", "Grasp the cup with the right gripper", 1.1],
["2.5–5.6 s", "Move the cup over the tray", 3.1],
["5.6–8.0 s", "Place the cup on the tray and release it", 2.4],
] as [string, string, number][],
},
{
title: "Wipe a section of the counter",
duration: "18.0 s",
rows: [
["0.0–2.0 s", "Pick up the sponge", 2],
["2.0–15.5 s", "Wipe the counter with the sponge", 13.5],
["15.5–18.0 s", "Place the sponge beside the sink", 2.5],
] as [string, string, number][],
},
];
const examples: Record<string, { label: string; text: string }[]> = {
Plans: [
{
label: "At 2.5 s · after grasping the cup",
text: "1. Move the cup over the tray.\n2. Place the cup on the tray and release it.",
},
{
label: "At 5.6 s · after moving the cup",
text: "1. Place the cup on the tray and release it.",
},
],
Memory: [
{ label: "At 2.5 s · completed action", text: "I picked up the cup." },
{
label: "At 15.5 s · after the wiping phase",
text: "I picked up the sponge and wiped the counter.",
},
],
"Task rephrasings": [
{
label: "Original task · place the cup on the tray",
text: "Move the cup onto the tray.",
},
{
label: "Same objects, action and destination",
text: "Could you put the cup on the tray, please?",
},
],
"Interjections & speech": [
{
label: "At 2.5 s · before transporting the cup",
text: "User: “Now move the cup over the tray, please.”\nRobot: “On it.”",
},
{
label: "At 15.5 s · before putting down the sponge",
text: "User: “Place the sponge beside the sink.”\nRobot: “Okay.”",
},
],
"Visual questions": [
{
label: "At 2.5 s · object state",
text: 'Q: What is the state of the cup?\nA: {"label":"cup","attribute":"state","value":"held by the right gripper"}',
},
{
label: "At 8.0 s · spatial relation",
text: 'Q: Where is the cup relative to the tray?\nA: {"subject":"cup","relation":"on","object":"tray"}',
},
],
};
const explanations: Record<string, string> = {
Subtasks:
"One meaningful action phase per segment. Reach, grasp, move and release can have separate boundaries; a sustained action stays together while its purpose is unchanged.",
Plans:
"A plan lists the remaining subtasks at each boundary. Completed actions disappear as the episode progresses.",
Memory:
"Short first-person summaries of completed work, updated at subtask boundaries. Keep useful outcomes rather than replaying every motion.",
"Task rephrasings":
"Different wording for the same episode-level instruction. These do not create new temporal segments or change the task.",
"Interjections & speech":
"A short user cue and paired robot acknowledgement at a subtask transition. The request matches what the recorded robot does next.",
"Visual questions":
"A question and a structured answer grounded in a sampled frame. These are point-in-time annotations, not action spans.",
};
export default function AnnotationExamples({ custom }: { custom: boolean }) {
const [type, setType] = useState("Subtasks");
return (
<section className="annotation-examples" aria-labelledby="examples-title">
<div className="examples-heading">
<Layers3 size={16} />
<h3 id="examples-title">What will the annotations look like?</h3>
<span>Illustrative examples</span>
</div>
<div className="example-tabs" aria-label="Example annotation type">
{types.map((t) => (
<button
key={t}
className={t === type ? "active" : ""}
aria-pressed={t === type}
onClick={() => setType(t)}
>
{t}
</button>
))}
</div>
<p className="examples-explanation">{explanations[type]}</p>
<div className="example-pair">
{type === "Subtasks"
? phases.map((example, index) => (
<article className="example-card" key={example.title}>
<div className="example-kicker">
EXAMPLE {index + 1}
<span>
<Clock3 size={11} />
{example.duration}
</span>
</div>
<h4>{example.title}</h4>
<div
className="example-timeline"
aria-label={`Illustrated timeline: ${example.rows.length} action phases`}
>
{example.rows.map(([time, text, seconds], i) => (
<span
key={time}
style={{ flex: seconds }}
className={`phase-${i}`}
title={`${time}: ${text}`}
/>
))}
</div>
<div className="example-rows">
{example.rows.map(([time, text], i) => (
<div key={time}>
<span className={`phase-dot phase-${i}`} />
<code>{time}</code>
<span>{text}</span>
</div>
))}
</div>
</article>
))
: examples[type].map((example, index) => (
<article className="example-card" key={example.label}>
<div className="example-kicker">EXAMPLE {index + 1}</div>
<h4>{example.label}</h4>
<p className="example-output">{example.text}</p>
</article>
))}
</div>
<p className="example-footnote">
Illustrations of the default style, not predictions for your dataset.
Boundaries depend on the visible action.
{custom
? " Your custom prompts may change the wording and granularity."
: ""}
</p>
</section>
);
}
|