[{"data":1,"prerenderedAt":3314},["ShallowReactive",2],{"content-query-eYWh5CmMi1":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"body":10,"_type":3308,"_id":3309,"_source":3310,"_file":3311,"_stem":3312,"_extension":3313},"\u002Fdocs\u002Ffeatures\u002Fvisualization-platform","features",false,"","Visualization Platform","Log, stream, and visualize multimodal data from your robots, sensors, cameras, and AI systems in real time.",{"type":11,"children":12,"toc":3270},"root",[13,21,35,40,45,49,56,61,71,76,133,136,142,149,154,186,199,214,220,225,249,255,260,283,286,292,297,391,396,401,519,524,527,533,545,600,605,610,613,619,624,701,729,741,764,767,773,779,784,876,882,887,941,947,960,1052,1073,1079,1084,1130,1136,1141,1187,1190,1196,1202,1247,1253,1266,1289,1295,1300,1386,1392,1405,1491,1494,1500,1505,1599,1604,1607,1613,1619,1624,1663,1668,1674,1679,1717,1720,1726,1731,1856,1859,1865,1870,1986,1989,1995,2000,2237,2266,2269,2275,2280,2634,2637,2643,2648,2870,2873,2879,2891,2929,2934,2953,2958,3023,3026,3032,3037,3105,3108,3114,3243,3246,3252,3264],{"type":14,"tag":15,"props":16,"children":18},"element","h1",{"id":17},"visualization-platform",[19],{"type":20,"value":8},"text",{"type":14,"tag":22,"props":23,"children":24},"p",{},[25,27,33],{"type":20,"value":26},"Before you can build great robotics and AI systems, you need to ",{"type":14,"tag":28,"props":29,"children":30},"em",{},[31],{"type":20,"value":32},"see",{"type":20,"value":34}," what they're doing. A text log that says \"robot moved to position X\" tells you almost nothing. But watching a live 3D point cloud of your robot's lidar scan, overlaid with its camera feed and battery level — that tells you everything.",{"type":14,"tag":22,"props":36,"children":37},{},[38],{"type":20,"value":39},"That's what the CredVault Visualization Platform is for.",{"type":14,"tag":22,"props":41,"children":42},{},[43],{"type":20,"value":44},"It lets you log any kind of data — 3D scenes, images, sensor readings, GPS tracks, model metrics, text events — and stream it to a visual viewer in real time. You can also save recordings to file and replay them later, frame by frame, to debug exactly what went wrong and when.",{"type":14,"tag":46,"props":47,"children":48},"hr",{},[],{"type":14,"tag":50,"props":51,"children":53},"h2",{"id":52},"how-it-works",[54],{"type":20,"value":55},"How It Works",{"type":14,"tag":22,"props":57,"children":58},{},[59],{"type":20,"value":60},"The core idea is simple: you instrument your code with logging calls, and the viewer shows you everything as it happens.",{"type":14,"tag":62,"props":63,"children":65},"pre",{"code":64},"Your code  →  rr.log(...)  →  CredVault Viewer\n",[66],{"type":14,"tag":67,"props":68,"children":69},"code",{"__ignoreMap":7},[70],{"type":20,"value":64},{"type":14,"tag":22,"props":72,"children":73},{},[74],{"type":20,"value":75},"You decide what to log, when to log it, and how to organize it. The viewer handles the rest — rendering 3D scenes, plotting time-series, displaying images, and letting you scrub through time.",{"type":14,"tag":22,"props":77,"children":78},{},[79,81,87,89,95,97,103,104,110,112,117,118,124,125,131],{"type":20,"value":80},"Data is organized into ",{"type":14,"tag":82,"props":83,"children":84},"strong",{},[85],{"type":20,"value":86},"entities",{"type":20,"value":88}," (like ",{"type":14,"tag":67,"props":90,"children":92},{"className":91},[],[93],{"type":20,"value":94},"robot\u002Fcamera",{"type":20,"value":96},", ",{"type":14,"tag":67,"props":98,"children":100},{"className":99},[],[101],{"type":20,"value":102},"robot\u002Flidar",{"type":20,"value":96},{"type":14,"tag":67,"props":105,"children":107},{"className":106},[],[108],{"type":20,"value":109},"sensor\u002Ftemperature",{"type":20,"value":111},") and ",{"type":14,"tag":82,"props":113,"children":114},{},[115],{"type":20,"value":116},"timelines",{"type":20,"value":88},{"type":14,"tag":67,"props":119,"children":121},{"className":120},[],[122],{"type":20,"value":123},"frame",{"type":20,"value":96},{"type":14,"tag":67,"props":126,"children":128},{"className":127},[],[129],{"type":20,"value":130},"epoch",{"type":20,"value":132},", or wall-clock time). This means you can have dozens of data streams all synchronized on the same timeline, and scrub through them together.",{"type":14,"tag":46,"props":134,"children":135},{},[],{"type":14,"tag":50,"props":137,"children":139},{"id":138},"installation",[140],{"type":20,"value":141},"Installation",{"type":14,"tag":143,"props":144,"children":146},"h3",{"id":145},"python",[147],{"type":20,"value":148},"Python",{"type":14,"tag":22,"props":150,"children":151},{},[152],{"type":20,"value":153},"The Python SDK is the most common way to log data. Install it with pip:",{"type":14,"tag":62,"props":155,"children":159},{"code":156,"language":157,"meta":7,"className":158,"style":7},"pip install credvault-rerun-sdk\n","bash","language-bash shiki shiki-themes github-dark",[160],{"type":14,"tag":67,"props":161,"children":162},{"__ignoreMap":7},[163],{"type":14,"tag":164,"props":165,"children":168},"span",{"class":166,"line":167},"line",1,[169,175,181],{"type":14,"tag":164,"props":170,"children":172},{"style":171},"--shiki-default:#B392F0",[173],{"type":20,"value":174},"pip",{"type":14,"tag":164,"props":176,"children":178},{"style":177},"--shiki-default:#9ECBFF",[179],{"type":20,"value":180}," install",{"type":14,"tag":164,"props":182,"children":183},{"style":177},[184],{"type":20,"value":185}," credvault-rerun-sdk\n",{"type":14,"tag":22,"props":187,"children":188},{},[189,191,197],{"type":20,"value":190},"Requires Python 3.10 or higher. Once installed, import it as ",{"type":14,"tag":67,"props":192,"children":194},{"className":193},[],[195],{"type":20,"value":196},"rerun",{"type":20,"value":198},":",{"type":14,"tag":62,"props":200,"children":203},{"code":201,"language":145,"meta":7,"className":202,"style":7},"import rerun as rr\n","language-python shiki shiki-themes github-dark",[204],{"type":14,"tag":67,"props":205,"children":206},{"__ignoreMap":7},[207],{"type":14,"tag":164,"props":208,"children":209},{"class":166,"line":167},[210],{"type":14,"tag":164,"props":211,"children":212},{},[213],{"type":20,"value":201},{"type":14,"tag":143,"props":215,"children":217},{"id":216},"javascript-nodejs",[218],{"type":20,"value":219},"JavaScript \u002F Node.js",{"type":14,"tag":22,"props":221,"children":222},{},[223],{"type":20,"value":224},"If you're building a web application or Node.js service:",{"type":14,"tag":62,"props":226,"children":228},{"code":227,"language":157,"meta":7,"className":158,"style":7},"npm install @credvault\u002Frerun-viewer\n",[229],{"type":14,"tag":67,"props":230,"children":231},{"__ignoreMap":7},[232],{"type":14,"tag":164,"props":233,"children":234},{"class":166,"line":167},[235,240,244],{"type":14,"tag":164,"props":236,"children":237},{"style":171},[238],{"type":20,"value":239},"npm",{"type":14,"tag":164,"props":241,"children":242},{"style":177},[243],{"type":20,"value":180},{"type":14,"tag":164,"props":245,"children":246},{"style":177},[247],{"type":20,"value":248}," @credvault\u002Frerun-viewer\n",{"type":14,"tag":143,"props":250,"children":252},{"id":251},"react",[253],{"type":20,"value":254},"React",{"type":14,"tag":22,"props":256,"children":257},{},[258],{"type":20,"value":259},"If you want to embed the visualization viewer directly inside a React dashboard:",{"type":14,"tag":62,"props":261,"children":263},{"code":262,"language":157,"meta":7,"className":158,"style":7},"npm install @credvault\u002Frerun-viewer-react\n",[264],{"type":14,"tag":67,"props":265,"children":266},{"__ignoreMap":7},[267],{"type":14,"tag":164,"props":268,"children":269},{"class":166,"line":167},[270,274,278],{"type":14,"tag":164,"props":271,"children":272},{"style":171},[273],{"type":20,"value":239},{"type":14,"tag":164,"props":275,"children":276},{"style":177},[277],{"type":20,"value":180},{"type":14,"tag":164,"props":279,"children":280},{"style":177},[281],{"type":20,"value":282}," @credvault\u002Frerun-viewer-react\n",{"type":14,"tag":46,"props":284,"children":285},{},[],{"type":14,"tag":50,"props":287,"children":289},{"id":288},"your-first-visualization",[290],{"type":20,"value":291},"Your First Visualization",{"type":14,"tag":22,"props":293,"children":294},{},[295],{"type":20,"value":296},"Let's start with the simplest possible example — logging a 3D point and opening the viewer.",{"type":14,"tag":62,"props":298,"children":300},{"code":299,"language":145,"meta":7,"className":202,"style":7},"import rerun as rr\n\n# Initialize with a name for your recording\nrr.init(\"my_first_visualization\")\n\n# Open the viewer (spawns a child process)\nrr.spawn()\n\n# Log a 3D point cloud\nrr.log(\"scene\u002Fpoints\", rr.Points3D(positions=[[0, 0, 0], [1, 0, 0], [0, 1, 0]]))\n",[301],{"type":14,"tag":67,"props":302,"children":303},{"__ignoreMap":7},[304,311,321,330,339,347,356,365,373,382],{"type":14,"tag":164,"props":305,"children":306},{"class":166,"line":167},[307],{"type":14,"tag":164,"props":308,"children":309},{},[310],{"type":20,"value":201},{"type":14,"tag":164,"props":312,"children":314},{"class":166,"line":313},2,[315],{"type":14,"tag":164,"props":316,"children":318},{"emptyLinePlaceholder":317},true,[319],{"type":20,"value":320},"\n",{"type":14,"tag":164,"props":322,"children":324},{"class":166,"line":323},3,[325],{"type":14,"tag":164,"props":326,"children":327},{},[328],{"type":20,"value":329},"# Initialize with a name for your recording\n",{"type":14,"tag":164,"props":331,"children":333},{"class":166,"line":332},4,[334],{"type":14,"tag":164,"props":335,"children":336},{},[337],{"type":20,"value":338},"rr.init(\"my_first_visualization\")\n",{"type":14,"tag":164,"props":340,"children":342},{"class":166,"line":341},5,[343],{"type":14,"tag":164,"props":344,"children":345},{"emptyLinePlaceholder":317},[346],{"type":20,"value":320},{"type":14,"tag":164,"props":348,"children":350},{"class":166,"line":349},6,[351],{"type":14,"tag":164,"props":352,"children":353},{},[354],{"type":20,"value":355},"# Open the viewer (spawns a child process)\n",{"type":14,"tag":164,"props":357,"children":359},{"class":166,"line":358},7,[360],{"type":14,"tag":164,"props":361,"children":362},{},[363],{"type":20,"value":364},"rr.spawn()\n",{"type":14,"tag":164,"props":366,"children":368},{"class":166,"line":367},8,[369],{"type":14,"tag":164,"props":370,"children":371},{"emptyLinePlaceholder":317},[372],{"type":20,"value":320},{"type":14,"tag":164,"props":374,"children":376},{"class":166,"line":375},9,[377],{"type":14,"tag":164,"props":378,"children":379},{},[380],{"type":20,"value":381},"# Log a 3D point cloud\n",{"type":14,"tag":164,"props":383,"children":385},{"class":166,"line":384},10,[386],{"type":14,"tag":164,"props":387,"children":388},{},[389],{"type":20,"value":390},"rr.log(\"scene\u002Fpoints\", rr.Points3D(positions=[[0, 0, 0], [1, 0, 0], [0, 1, 0]]))\n",{"type":14,"tag":22,"props":392,"children":393},{},[394],{"type":20,"value":395},"Run this and the CredVault viewer opens automatically, showing three points in 3D space.",{"type":14,"tag":22,"props":397,"children":398},{},[399],{"type":20,"value":400},"Now let's make it more interesting by adding a timeline so you can scrub through frames:",{"type":14,"tag":62,"props":402,"children":404},{"code":403,"language":145,"meta":7,"className":202,"style":7},"import rerun as rr\nimport numpy as np\n\nrr.init(\"timeline_example\")\nrr.spawn()\n\nfor frame in range(100):\n    # Tell the viewer which frame this data belongs to\n    rr.set_time(\"frame\", sequence=frame)\n\n    # Log a point that moves over time\n    x = np.sin(frame * 0.1)\n    y = np.cos(frame * 0.1)\n    rr.log(\"scene\u002Fmoving_point\", rr.Points3D(positions=[[x, y, 0]]))\n",[405],{"type":14,"tag":67,"props":406,"children":407},{"__ignoreMap":7},[408,415,423,430,438,445,452,460,468,476,483,492,501,510],{"type":14,"tag":164,"props":409,"children":410},{"class":166,"line":167},[411],{"type":14,"tag":164,"props":412,"children":413},{},[414],{"type":20,"value":201},{"type":14,"tag":164,"props":416,"children":417},{"class":166,"line":313},[418],{"type":14,"tag":164,"props":419,"children":420},{},[421],{"type":20,"value":422},"import numpy as np\n",{"type":14,"tag":164,"props":424,"children":425},{"class":166,"line":323},[426],{"type":14,"tag":164,"props":427,"children":428},{"emptyLinePlaceholder":317},[429],{"type":20,"value":320},{"type":14,"tag":164,"props":431,"children":432},{"class":166,"line":332},[433],{"type":14,"tag":164,"props":434,"children":435},{},[436],{"type":20,"value":437},"rr.init(\"timeline_example\")\n",{"type":14,"tag":164,"props":439,"children":440},{"class":166,"line":341},[441],{"type":14,"tag":164,"props":442,"children":443},{},[444],{"type":20,"value":364},{"type":14,"tag":164,"props":446,"children":447},{"class":166,"line":349},[448],{"type":14,"tag":164,"props":449,"children":450},{"emptyLinePlaceholder":317},[451],{"type":20,"value":320},{"type":14,"tag":164,"props":453,"children":454},{"class":166,"line":358},[455],{"type":14,"tag":164,"props":456,"children":457},{},[458],{"type":20,"value":459},"for frame in range(100):\n",{"type":14,"tag":164,"props":461,"children":462},{"class":166,"line":367},[463],{"type":14,"tag":164,"props":464,"children":465},{},[466],{"type":20,"value":467},"    # Tell the viewer which frame this data belongs to\n",{"type":14,"tag":164,"props":469,"children":470},{"class":166,"line":375},[471],{"type":14,"tag":164,"props":472,"children":473},{},[474],{"type":20,"value":475},"    rr.set_time(\"frame\", sequence=frame)\n",{"type":14,"tag":164,"props":477,"children":478},{"class":166,"line":384},[479],{"type":14,"tag":164,"props":480,"children":481},{"emptyLinePlaceholder":317},[482],{"type":20,"value":320},{"type":14,"tag":164,"props":484,"children":486},{"class":166,"line":485},11,[487],{"type":14,"tag":164,"props":488,"children":489},{},[490],{"type":20,"value":491},"    # Log a point that moves over time\n",{"type":14,"tag":164,"props":493,"children":495},{"class":166,"line":494},12,[496],{"type":14,"tag":164,"props":497,"children":498},{},[499],{"type":20,"value":500},"    x = np.sin(frame * 0.1)\n",{"type":14,"tag":164,"props":502,"children":504},{"class":166,"line":503},13,[505],{"type":14,"tag":164,"props":506,"children":507},{},[508],{"type":20,"value":509},"    y = np.cos(frame * 0.1)\n",{"type":14,"tag":164,"props":511,"children":513},{"class":166,"line":512},14,[514],{"type":14,"tag":164,"props":515,"children":516},{},[517],{"type":20,"value":518},"    rr.log(\"scene\u002Fmoving_point\", rr.Points3D(positions=[[x, y, 0]]))\n",{"type":14,"tag":22,"props":520,"children":521},{},[522],{"type":20,"value":523},"Now you can drag the timeline slider in the viewer and watch the point move.",{"type":14,"tag":46,"props":525,"children":526},{},[],{"type":14,"tag":50,"props":528,"children":530},{"id":529},"understanding-entities-and-paths",[531],{"type":20,"value":532},"Understanding Entities and Paths",{"type":14,"tag":22,"props":534,"children":535},{},[536,538,543],{"type":20,"value":537},"Every piece of data you log goes to an ",{"type":14,"tag":82,"props":539,"children":540},{},[541],{"type":20,"value":542},"entity path",{"type":20,"value":544}," — a slash-separated string that organizes your data like a file system.",{"type":14,"tag":62,"props":546,"children":548},{"code":547,"language":145,"meta":7,"className":202,"style":7},"rr.log(\"robot\u002Fcamera\u002Frgb\", ...)        # camera image\nrr.log(\"robot\u002Fcamera\u002Fdepth\", ...)      # depth image\nrr.log(\"robot\u002Flidar\", ...)             # lidar point cloud\nrr.log(\"robot\u002Ftransform\", ...)         # robot position\nrr.log(\"metrics\u002Floss\", ...)            # training loss\nrr.log(\"metrics\u002Faccuracy\", ...)        # training accuracy\n",[549],{"type":14,"tag":67,"props":550,"children":551},{"__ignoreMap":7},[552,560,568,576,584,592],{"type":14,"tag":164,"props":553,"children":554},{"class":166,"line":167},[555],{"type":14,"tag":164,"props":556,"children":557},{},[558],{"type":20,"value":559},"rr.log(\"robot\u002Fcamera\u002Frgb\", ...)        # camera image\n",{"type":14,"tag":164,"props":561,"children":562},{"class":166,"line":313},[563],{"type":14,"tag":164,"props":564,"children":565},{},[566],{"type":20,"value":567},"rr.log(\"robot\u002Fcamera\u002Fdepth\", ...)      # depth image\n",{"type":14,"tag":164,"props":569,"children":570},{"class":166,"line":323},[571],{"type":14,"tag":164,"props":572,"children":573},{},[574],{"type":20,"value":575},"rr.log(\"robot\u002Flidar\", ...)             # lidar point cloud\n",{"type":14,"tag":164,"props":577,"children":578},{"class":166,"line":332},[579],{"type":14,"tag":164,"props":580,"children":581},{},[582],{"type":20,"value":583},"rr.log(\"robot\u002Ftransform\", ...)         # robot position\n",{"type":14,"tag":164,"props":585,"children":586},{"class":166,"line":341},[587],{"type":14,"tag":164,"props":588,"children":589},{},[590],{"type":20,"value":591},"rr.log(\"metrics\u002Floss\", ...)            # training loss\n",{"type":14,"tag":164,"props":593,"children":594},{"class":166,"line":349},[595],{"type":14,"tag":164,"props":596,"children":597},{},[598],{"type":20,"value":599},"rr.log(\"metrics\u002Faccuracy\", ...)        # training accuracy\n",{"type":14,"tag":22,"props":601,"children":602},{},[603],{"type":20,"value":604},"The viewer shows these as a tree on the left side. You can expand and collapse branches, toggle visibility, and inspect individual entities. Think of it like a scene graph — everything has a place in the hierarchy.",{"type":14,"tag":22,"props":606,"children":607},{},[608],{"type":20,"value":609},"Good entity paths make your recordings much easier to navigate. Use descriptive names and group related data under the same parent path.",{"type":14,"tag":46,"props":611,"children":612},{},[],{"type":14,"tag":50,"props":614,"children":616},{"id":615},"understanding-timelines",[617],{"type":20,"value":618},"Understanding Timelines",{"type":14,"tag":22,"props":620,"children":621},{},[622],{"type":20,"value":623},"A timeline is how you associate data with a point in time. You can have multiple timelines in the same recording.",{"type":14,"tag":62,"props":625,"children":627},{"code":626,"language":145,"meta":7,"className":202,"style":7},"# Frame-based timeline (for robotics, video)\nrr.set_time(\"frame\", sequence=42)\n\n# Step-based timeline (for ML training)\nrr.set_time(\"training_step\", sequence=1000)\n\n# Wall-clock time\nimport time\nrr.set_time(\"wall_time\", duration=time.time())\n",[628],{"type":14,"tag":67,"props":629,"children":630},{"__ignoreMap":7},[631,639,647,654,662,670,677,685,693],{"type":14,"tag":164,"props":632,"children":633},{"class":166,"line":167},[634],{"type":14,"tag":164,"props":635,"children":636},{},[637],{"type":20,"value":638},"# Frame-based timeline (for robotics, video)\n",{"type":14,"tag":164,"props":640,"children":641},{"class":166,"line":313},[642],{"type":14,"tag":164,"props":643,"children":644},{},[645],{"type":20,"value":646},"rr.set_time(\"frame\", sequence=42)\n",{"type":14,"tag":164,"props":648,"children":649},{"class":166,"line":323},[650],{"type":14,"tag":164,"props":651,"children":652},{"emptyLinePlaceholder":317},[653],{"type":20,"value":320},{"type":14,"tag":164,"props":655,"children":656},{"class":166,"line":332},[657],{"type":14,"tag":164,"props":658,"children":659},{},[660],{"type":20,"value":661},"# Step-based timeline (for ML training)\n",{"type":14,"tag":164,"props":663,"children":664},{"class":166,"line":341},[665],{"type":14,"tag":164,"props":666,"children":667},{},[668],{"type":20,"value":669},"rr.set_time(\"training_step\", sequence=1000)\n",{"type":14,"tag":164,"props":671,"children":672},{"class":166,"line":349},[673],{"type":14,"tag":164,"props":674,"children":675},{"emptyLinePlaceholder":317},[676],{"type":20,"value":320},{"type":14,"tag":164,"props":678,"children":679},{"class":166,"line":358},[680],{"type":14,"tag":164,"props":681,"children":682},{},[683],{"type":20,"value":684},"# Wall-clock time\n",{"type":14,"tag":164,"props":686,"children":687},{"class":166,"line":367},[688],{"type":14,"tag":164,"props":689,"children":690},{},[691],{"type":20,"value":692},"import time\n",{"type":14,"tag":164,"props":694,"children":695},{"class":166,"line":375},[696],{"type":14,"tag":164,"props":697,"children":698},{},[699],{"type":20,"value":700},"rr.set_time(\"wall_time\", duration=time.time())\n",{"type":14,"tag":22,"props":702,"children":703},{},[704,706,712,714,720,722,727],{"type":20,"value":705},"After calling ",{"type":14,"tag":67,"props":707,"children":709},{"className":708},[],[710],{"type":20,"value":711},"set_time",{"type":20,"value":713},", every ",{"type":14,"tag":67,"props":715,"children":717},{"className":716},[],[718],{"type":20,"value":719},"rr.log",{"type":20,"value":721}," call until the next ",{"type":14,"tag":67,"props":723,"children":725},{"className":724},[],[726],{"type":20,"value":711},{"type":20,"value":728}," will be associated with that timestamp. This is how the viewer knows where to place your data on the timeline.",{"type":14,"tag":22,"props":730,"children":731},{},[732,734,739],{"type":20,"value":733},"You can also have ",{"type":14,"tag":82,"props":735,"children":736},{},[737],{"type":20,"value":738},"static data",{"type":20,"value":740}," — data that has no time and exists across all timelines. Use this for things that don't change, like camera calibration parameters or a 3D model of your environment:",{"type":14,"tag":62,"props":742,"children":744},{"code":743,"language":145,"meta":7,"className":202,"style":7},"# This camera calibration is valid for the entire recording\nrr.log(\"robot\u002Fcamera\", rr.Pinhole(focal_length=500, width=640, height=480), static=True)\n",[745],{"type":14,"tag":67,"props":746,"children":747},{"__ignoreMap":7},[748,756],{"type":14,"tag":164,"props":749,"children":750},{"class":166,"line":167},[751],{"type":14,"tag":164,"props":752,"children":753},{},[754],{"type":20,"value":755},"# This camera calibration is valid for the entire recording\n",{"type":14,"tag":164,"props":757,"children":758},{"class":166,"line":313},[759],{"type":14,"tag":164,"props":760,"children":761},{},[762],{"type":20,"value":763},"rr.log(\"robot\u002Fcamera\", rr.Pinhole(focal_length=500, width=640, height=480), static=True)\n",{"type":14,"tag":46,"props":765,"children":766},{},[],{"type":14,"tag":50,"props":768,"children":770},{"id":769},"logging-3d-data",[771],{"type":20,"value":772},"Logging 3D Data",{"type":14,"tag":143,"props":774,"children":776},{"id":775},"point-clouds",[777],{"type":20,"value":778},"Point Clouds",{"type":14,"tag":22,"props":780,"children":781},{},[782],{"type":20,"value":783},"Point clouds are the most common 3D data type in robotics. They come from lidar sensors, depth cameras, and 3D reconstruction algorithms.",{"type":14,"tag":62,"props":785,"children":787},{"code":786,"language":145,"meta":7,"className":202,"style":7},"import numpy as np\n\n# Generate a simple point cloud\npositions = np.random.uniform(-1, 1, (1000, 3))\ncolors = np.random.uniform(0, 255, (1000, 3)).astype(np.uint8)\n\nrr.log(\"scene\u002Flidar\", rr.Points3D(\n    positions=positions,\n    colors=colors,\n    radii=0.02  # size of each point\n))\n",[788],{"type":14,"tag":67,"props":789,"children":790},{"__ignoreMap":7},[791,798,805,813,821,829,836,844,852,860,868],{"type":14,"tag":164,"props":792,"children":793},{"class":166,"line":167},[794],{"type":14,"tag":164,"props":795,"children":796},{},[797],{"type":20,"value":422},{"type":14,"tag":164,"props":799,"children":800},{"class":166,"line":313},[801],{"type":14,"tag":164,"props":802,"children":803},{"emptyLinePlaceholder":317},[804],{"type":20,"value":320},{"type":14,"tag":164,"props":806,"children":807},{"class":166,"line":323},[808],{"type":14,"tag":164,"props":809,"children":810},{},[811],{"type":20,"value":812},"# Generate a simple point cloud\n",{"type":14,"tag":164,"props":814,"children":815},{"class":166,"line":332},[816],{"type":14,"tag":164,"props":817,"children":818},{},[819],{"type":20,"value":820},"positions = np.random.uniform(-1, 1, (1000, 3))\n",{"type":14,"tag":164,"props":822,"children":823},{"class":166,"line":341},[824],{"type":14,"tag":164,"props":825,"children":826},{},[827],{"type":20,"value":828},"colors = np.random.uniform(0, 255, (1000, 3)).astype(np.uint8)\n",{"type":14,"tag":164,"props":830,"children":831},{"class":166,"line":349},[832],{"type":14,"tag":164,"props":833,"children":834},{"emptyLinePlaceholder":317},[835],{"type":20,"value":320},{"type":14,"tag":164,"props":837,"children":838},{"class":166,"line":358},[839],{"type":14,"tag":164,"props":840,"children":841},{},[842],{"type":20,"value":843},"rr.log(\"scene\u002Flidar\", rr.Points3D(\n",{"type":14,"tag":164,"props":845,"children":846},{"class":166,"line":367},[847],{"type":14,"tag":164,"props":848,"children":849},{},[850],{"type":20,"value":851},"    positions=positions,\n",{"type":14,"tag":164,"props":853,"children":854},{"class":166,"line":375},[855],{"type":14,"tag":164,"props":856,"children":857},{},[858],{"type":20,"value":859},"    colors=colors,\n",{"type":14,"tag":164,"props":861,"children":862},{"class":166,"line":384},[863],{"type":14,"tag":164,"props":864,"children":865},{},[866],{"type":20,"value":867},"    radii=0.02  # size of each point\n",{"type":14,"tag":164,"props":869,"children":870},{"class":166,"line":485},[871],{"type":14,"tag":164,"props":872,"children":873},{},[874],{"type":20,"value":875},"))\n",{"type":14,"tag":143,"props":877,"children":879},{"id":878},"_3d-bounding-boxes",[880],{"type":20,"value":881},"3D Bounding Boxes",{"type":14,"tag":22,"props":883,"children":884},{},[885],{"type":20,"value":886},"Use bounding boxes to show detected objects in 3D space:",{"type":14,"tag":62,"props":888,"children":890},{"code":889,"language":145,"meta":7,"className":202,"style":7},"rr.log(\"scene\u002Fdetections\", rr.Boxes3D(\n    centers=[[1.0, 0.0, 0.5], [3.0, 1.0, 0.5]],\n    half_sizes=[[0.5, 0.3, 0.5], [0.4, 0.4, 0.5]],\n    labels=[\"robot_arm\", \"conveyor_belt\"],\n    colors=[[0, 255, 0], [255, 165, 0]]\n))\n",[891],{"type":14,"tag":67,"props":892,"children":893},{"__ignoreMap":7},[894,902,910,918,926,934],{"type":14,"tag":164,"props":895,"children":896},{"class":166,"line":167},[897],{"type":14,"tag":164,"props":898,"children":899},{},[900],{"type":20,"value":901},"rr.log(\"scene\u002Fdetections\", rr.Boxes3D(\n",{"type":14,"tag":164,"props":903,"children":904},{"class":166,"line":313},[905],{"type":14,"tag":164,"props":906,"children":907},{},[908],{"type":20,"value":909},"    centers=[[1.0, 0.0, 0.5], [3.0, 1.0, 0.5]],\n",{"type":14,"tag":164,"props":911,"children":912},{"class":166,"line":323},[913],{"type":14,"tag":164,"props":914,"children":915},{},[916],{"type":20,"value":917},"    half_sizes=[[0.5, 0.3, 0.5], [0.4, 0.4, 0.5]],\n",{"type":14,"tag":164,"props":919,"children":920},{"class":166,"line":332},[921],{"type":14,"tag":164,"props":922,"children":923},{},[924],{"type":20,"value":925},"    labels=[\"robot_arm\", \"conveyor_belt\"],\n",{"type":14,"tag":164,"props":927,"children":928},{"class":166,"line":341},[929],{"type":14,"tag":164,"props":930,"children":931},{},[932],{"type":20,"value":933},"    colors=[[0, 255, 0], [255, 165, 0]]\n",{"type":14,"tag":164,"props":935,"children":936},{"class":166,"line":349},[937],{"type":14,"tag":164,"props":938,"children":939},{},[940],{"type":20,"value":875},{"type":14,"tag":143,"props":942,"children":944},{"id":943},"transforms-and-coordinate-frames",[945],{"type":20,"value":946},"Transforms and Coordinate Frames",{"type":14,"tag":22,"props":948,"children":949},{},[950,952,958],{"type":20,"value":951},"When you have a robot with multiple joints or sensors, you need to track how each part relates to the others. Use ",{"type":14,"tag":67,"props":953,"children":955},{"className":954},[],[956],{"type":20,"value":957},"Transform3D",{"type":20,"value":959}," to define the position and orientation of each frame:",{"type":14,"tag":62,"props":961,"children":963},{"code":962,"language":145,"meta":7,"className":202,"style":7},"# Robot base position in the world\nrr.log(\"robot\u002Fbase\", rr.Transform3D(\n    translation=[x, y, 0],\n    rotation=rr.Quaternion(xyzw=[0, 0, np.sin(yaw\u002F2), np.cos(yaw\u002F2)])\n))\n\n# Camera mounted on the robot (relative to base)\nrr.log(\"robot\u002Fbase\u002Fcamera\", rr.Transform3D(\n    translation=[0.2, 0, 0.5],  # 20cm forward, 50cm up\n    rotation=rr.Quaternion(xyzw=[0, 0, 0, 1])  # no rotation\n))\n",[964],{"type":14,"tag":67,"props":965,"children":966},{"__ignoreMap":7},[967,975,983,991,999,1006,1013,1021,1029,1037,1045],{"type":14,"tag":164,"props":968,"children":969},{"class":166,"line":167},[970],{"type":14,"tag":164,"props":971,"children":972},{},[973],{"type":20,"value":974},"# Robot base position in the world\n",{"type":14,"tag":164,"props":976,"children":977},{"class":166,"line":313},[978],{"type":14,"tag":164,"props":979,"children":980},{},[981],{"type":20,"value":982},"rr.log(\"robot\u002Fbase\", rr.Transform3D(\n",{"type":14,"tag":164,"props":984,"children":985},{"class":166,"line":323},[986],{"type":14,"tag":164,"props":987,"children":988},{},[989],{"type":20,"value":990},"    translation=[x, y, 0],\n",{"type":14,"tag":164,"props":992,"children":993},{"class":166,"line":332},[994],{"type":14,"tag":164,"props":995,"children":996},{},[997],{"type":20,"value":998},"    rotation=rr.Quaternion(xyzw=[0, 0, np.sin(yaw\u002F2), np.cos(yaw\u002F2)])\n",{"type":14,"tag":164,"props":1000,"children":1001},{"class":166,"line":341},[1002],{"type":14,"tag":164,"props":1003,"children":1004},{},[1005],{"type":20,"value":875},{"type":14,"tag":164,"props":1007,"children":1008},{"class":166,"line":349},[1009],{"type":14,"tag":164,"props":1010,"children":1011},{"emptyLinePlaceholder":317},[1012],{"type":20,"value":320},{"type":14,"tag":164,"props":1014,"children":1015},{"class":166,"line":358},[1016],{"type":14,"tag":164,"props":1017,"children":1018},{},[1019],{"type":20,"value":1020},"# Camera mounted on the robot (relative to base)\n",{"type":14,"tag":164,"props":1022,"children":1023},{"class":166,"line":367},[1024],{"type":14,"tag":164,"props":1025,"children":1026},{},[1027],{"type":20,"value":1028},"rr.log(\"robot\u002Fbase\u002Fcamera\", rr.Transform3D(\n",{"type":14,"tag":164,"props":1030,"children":1031},{"class":166,"line":375},[1032],{"type":14,"tag":164,"props":1033,"children":1034},{},[1035],{"type":20,"value":1036},"    translation=[0.2, 0, 0.5],  # 20cm forward, 50cm up\n",{"type":14,"tag":164,"props":1038,"children":1039},{"class":166,"line":384},[1040],{"type":14,"tag":164,"props":1041,"children":1042},{},[1043],{"type":20,"value":1044},"    rotation=rr.Quaternion(xyzw=[0, 0, 0, 1])  # no rotation\n",{"type":14,"tag":164,"props":1046,"children":1047},{"class":166,"line":485},[1048],{"type":14,"tag":164,"props":1049,"children":1050},{},[1051],{"type":20,"value":875},{"type":14,"tag":22,"props":1053,"children":1054},{},[1055,1057,1063,1065,1071],{"type":20,"value":1056},"The viewer understands the parent-child relationship between ",{"type":14,"tag":67,"props":1058,"children":1060},{"className":1059},[],[1061],{"type":20,"value":1062},"robot\u002Fbase",{"type":20,"value":1064}," and ",{"type":14,"tag":67,"props":1066,"children":1068},{"className":1067},[],[1069],{"type":20,"value":1070},"robot\u002Fbase\u002Fcamera",{"type":20,"value":1072},", so the camera moves with the robot automatically.",{"type":14,"tag":143,"props":1074,"children":1076},{"id":1075},"arrows-and-vectors",[1077],{"type":20,"value":1078},"Arrows and Vectors",{"type":14,"tag":22,"props":1080,"children":1081},{},[1082],{"type":20,"value":1083},"Useful for showing velocity, force, or direction:",{"type":14,"tag":62,"props":1085,"children":1087},{"code":1086,"language":145,"meta":7,"className":202,"style":7},"rr.log(\"robot\u002Fvelocity\", rr.Arrows3D(\n    origins=[[0, 0, 0]],\n    vectors=[[vx, vy, vz]],\n    colors=[[0, 200, 255]]\n))\n",[1088],{"type":14,"tag":67,"props":1089,"children":1090},{"__ignoreMap":7},[1091,1099,1107,1115,1123],{"type":14,"tag":164,"props":1092,"children":1093},{"class":166,"line":167},[1094],{"type":14,"tag":164,"props":1095,"children":1096},{},[1097],{"type":20,"value":1098},"rr.log(\"robot\u002Fvelocity\", rr.Arrows3D(\n",{"type":14,"tag":164,"props":1100,"children":1101},{"class":166,"line":313},[1102],{"type":14,"tag":164,"props":1103,"children":1104},{},[1105],{"type":20,"value":1106},"    origins=[[0, 0, 0]],\n",{"type":14,"tag":164,"props":1108,"children":1109},{"class":166,"line":323},[1110],{"type":14,"tag":164,"props":1111,"children":1112},{},[1113],{"type":20,"value":1114},"    vectors=[[vx, vy, vz]],\n",{"type":14,"tag":164,"props":1116,"children":1117},{"class":166,"line":332},[1118],{"type":14,"tag":164,"props":1119,"children":1120},{},[1121],{"type":20,"value":1122},"    colors=[[0, 200, 255]]\n",{"type":14,"tag":164,"props":1124,"children":1125},{"class":166,"line":341},[1126],{"type":14,"tag":164,"props":1127,"children":1128},{},[1129],{"type":20,"value":875},{"type":14,"tag":143,"props":1131,"children":1133},{"id":1132},"_3d-meshes",[1134],{"type":20,"value":1135},"3D Meshes",{"type":14,"tag":22,"props":1137,"children":1138},{},[1139],{"type":20,"value":1140},"Load and display 3D models of your robots or environment:",{"type":14,"tag":62,"props":1142,"children":1144},{"code":1143,"language":145,"meta":7,"className":202,"style":7},"rr.log(\"scene\u002Frobot_model\", rr.Mesh3D(\n    vertex_positions=vertices,      # Nx3 array\n    triangle_indices=faces,         # Mx3 array of vertex indices\n    vertex_colors=colors            # optional per-vertex colors\n))\n",[1145],{"type":14,"tag":67,"props":1146,"children":1147},{"__ignoreMap":7},[1148,1156,1164,1172,1180],{"type":14,"tag":164,"props":1149,"children":1150},{"class":166,"line":167},[1151],{"type":14,"tag":164,"props":1152,"children":1153},{},[1154],{"type":20,"value":1155},"rr.log(\"scene\u002Frobot_model\", rr.Mesh3D(\n",{"type":14,"tag":164,"props":1157,"children":1158},{"class":166,"line":313},[1159],{"type":14,"tag":164,"props":1160,"children":1161},{},[1162],{"type":20,"value":1163},"    vertex_positions=vertices,      # Nx3 array\n",{"type":14,"tag":164,"props":1165,"children":1166},{"class":166,"line":323},[1167],{"type":14,"tag":164,"props":1168,"children":1169},{},[1170],{"type":20,"value":1171},"    triangle_indices=faces,         # Mx3 array of vertex indices\n",{"type":14,"tag":164,"props":1173,"children":1174},{"class":166,"line":332},[1175],{"type":14,"tag":164,"props":1176,"children":1177},{},[1178],{"type":20,"value":1179},"    vertex_colors=colors            # optional per-vertex colors\n",{"type":14,"tag":164,"props":1181,"children":1182},{"class":166,"line":341},[1183],{"type":14,"tag":164,"props":1184,"children":1185},{},[1186],{"type":20,"value":875},{"type":14,"tag":46,"props":1188,"children":1189},{},[],{"type":14,"tag":50,"props":1191,"children":1193},{"id":1192},"logging-images-and-video",[1194],{"type":20,"value":1195},"Logging Images and Video",{"type":14,"tag":143,"props":1197,"children":1199},{"id":1198},"rgb-images",[1200],{"type":20,"value":1201},"RGB Images",{"type":14,"tag":62,"props":1203,"children":1205},{"code":1204,"language":145,"meta":7,"className":202,"style":7},"import numpy as np\n\n# From a numpy array (H x W x 3, uint8)\nimage = get_camera_frame()  # your function that returns a numpy array\nrr.log(\"robot\u002Fcamera\u002Frgb\", rr.Image(image))\n",[1206],{"type":14,"tag":67,"props":1207,"children":1208},{"__ignoreMap":7},[1209,1216,1223,1231,1239],{"type":14,"tag":164,"props":1210,"children":1211},{"class":166,"line":167},[1212],{"type":14,"tag":164,"props":1213,"children":1214},{},[1215],{"type":20,"value":422},{"type":14,"tag":164,"props":1217,"children":1218},{"class":166,"line":313},[1219],{"type":14,"tag":164,"props":1220,"children":1221},{"emptyLinePlaceholder":317},[1222],{"type":20,"value":320},{"type":14,"tag":164,"props":1224,"children":1225},{"class":166,"line":323},[1226],{"type":14,"tag":164,"props":1227,"children":1228},{},[1229],{"type":20,"value":1230},"# From a numpy array (H x W x 3, uint8)\n",{"type":14,"tag":164,"props":1232,"children":1233},{"class":166,"line":332},[1234],{"type":14,"tag":164,"props":1235,"children":1236},{},[1237],{"type":20,"value":1238},"image = get_camera_frame()  # your function that returns a numpy array\n",{"type":14,"tag":164,"props":1240,"children":1241},{"class":166,"line":341},[1242],{"type":14,"tag":164,"props":1243,"children":1244},{},[1245],{"type":20,"value":1246},"rr.log(\"robot\u002Fcamera\u002Frgb\", rr.Image(image))\n",{"type":14,"tag":143,"props":1248,"children":1250},{"id":1249},"depth-images",[1251],{"type":20,"value":1252},"Depth Images",{"type":14,"tag":22,"props":1254,"children":1255},{},[1256,1258,1264],{"type":20,"value":1257},"Depth images store distance values per pixel. The ",{"type":14,"tag":67,"props":1259,"children":1261},{"className":1260},[],[1262],{"type":20,"value":1263},"meter",{"type":20,"value":1265}," parameter tells the viewer what value represents 1 meter:",{"type":14,"tag":62,"props":1267,"children":1269},{"code":1268,"language":145,"meta":7,"className":202,"style":7},"depth = get_depth_frame()  # H x W array of uint16 values in millimeters\nrr.log(\"robot\u002Fcamera\u002Fdepth\", rr.DepthImage(depth, meter=1000.0))\n",[1270],{"type":14,"tag":67,"props":1271,"children":1272},{"__ignoreMap":7},[1273,1281],{"type":14,"tag":164,"props":1274,"children":1275},{"class":166,"line":167},[1276],{"type":14,"tag":164,"props":1277,"children":1278},{},[1279],{"type":20,"value":1280},"depth = get_depth_frame()  # H x W array of uint16 values in millimeters\n",{"type":14,"tag":164,"props":1282,"children":1283},{"class":166,"line":313},[1284],{"type":14,"tag":164,"props":1285,"children":1286},{},[1287],{"type":20,"value":1288},"rr.log(\"robot\u002Fcamera\u002Fdepth\", rr.DepthImage(depth, meter=1000.0))\n",{"type":14,"tag":143,"props":1290,"children":1292},{"id":1291},"segmentation-masks",[1293],{"type":20,"value":1294},"Segmentation Masks",{"type":14,"tag":22,"props":1296,"children":1297},{},[1298],{"type":20,"value":1299},"Segmentation images use integer labels per pixel. You can define what each label means using an annotation context:",{"type":14,"tag":62,"props":1301,"children":1303},{"code":1302,"language":145,"meta":7,"className":202,"style":7},"# Define what each class label means\nrr.log(\"annotations\", rr.AnnotationContext([\n    (0, \"background\"),\n    (1, \"robot\"),\n    (2, \"obstacle\"),\n    (3, \"target\"),\n]), static=True)\n\n# Log the segmentation mask\nrr.log(\"robot\u002Fcamera\u002Fsegmentation\", rr.SegmentationImage(mask_array))\n",[1304],{"type":14,"tag":67,"props":1305,"children":1306},{"__ignoreMap":7},[1307,1315,1323,1331,1339,1347,1355,1363,1370,1378],{"type":14,"tag":164,"props":1308,"children":1309},{"class":166,"line":167},[1310],{"type":14,"tag":164,"props":1311,"children":1312},{},[1313],{"type":20,"value":1314},"# Define what each class label means\n",{"type":14,"tag":164,"props":1316,"children":1317},{"class":166,"line":313},[1318],{"type":14,"tag":164,"props":1319,"children":1320},{},[1321],{"type":20,"value":1322},"rr.log(\"annotations\", rr.AnnotationContext([\n",{"type":14,"tag":164,"props":1324,"children":1325},{"class":166,"line":323},[1326],{"type":14,"tag":164,"props":1327,"children":1328},{},[1329],{"type":20,"value":1330},"    (0, \"background\"),\n",{"type":14,"tag":164,"props":1332,"children":1333},{"class":166,"line":332},[1334],{"type":14,"tag":164,"props":1335,"children":1336},{},[1337],{"type":20,"value":1338},"    (1, \"robot\"),\n",{"type":14,"tag":164,"props":1340,"children":1341},{"class":166,"line":341},[1342],{"type":14,"tag":164,"props":1343,"children":1344},{},[1345],{"type":20,"value":1346},"    (2, \"obstacle\"),\n",{"type":14,"tag":164,"props":1348,"children":1349},{"class":166,"line":349},[1350],{"type":14,"tag":164,"props":1351,"children":1352},{},[1353],{"type":20,"value":1354},"    (3, \"target\"),\n",{"type":14,"tag":164,"props":1356,"children":1357},{"class":166,"line":358},[1358],{"type":14,"tag":164,"props":1359,"children":1360},{},[1361],{"type":20,"value":1362},"]), static=True)\n",{"type":14,"tag":164,"props":1364,"children":1365},{"class":166,"line":367},[1366],{"type":14,"tag":164,"props":1367,"children":1368},{"emptyLinePlaceholder":317},[1369],{"type":20,"value":320},{"type":14,"tag":164,"props":1371,"children":1372},{"class":166,"line":375},[1373],{"type":14,"tag":164,"props":1374,"children":1375},{},[1376],{"type":20,"value":1377},"# Log the segmentation mask\n",{"type":14,"tag":164,"props":1379,"children":1380},{"class":166,"line":384},[1381],{"type":14,"tag":164,"props":1382,"children":1383},{},[1384],{"type":20,"value":1385},"rr.log(\"robot\u002Fcamera\u002Fsegmentation\", rr.SegmentationImage(mask_array))\n",{"type":14,"tag":143,"props":1387,"children":1389},{"id":1388},"camera-calibration",[1390],{"type":20,"value":1391},"Camera Calibration",{"type":14,"tag":22,"props":1393,"children":1394},{},[1395,1397,1403],{"type":20,"value":1396},"If you log a ",{"type":14,"tag":67,"props":1398,"children":1400},{"className":1399},[],[1401],{"type":20,"value":1402},"Pinhole",{"type":20,"value":1404}," to the same entity as your image, the viewer can correctly project 3D points onto the image plane:",{"type":14,"tag":62,"props":1406,"children":1408},{"code":1407,"language":145,"meta":7,"className":202,"style":7},"# Log camera intrinsics once (static)\nrr.log(\"robot\u002Fcamera\", rr.Pinhole(\n    focal_length=[fx, fy],\n    principal_point=[cx, cy],\n    width=640,\n    height=480\n), static=True)\n\n# Log images on the same entity\nrr.log(\"robot\u002Fcamera\", rr.Image(frame))\n",[1409],{"type":14,"tag":67,"props":1410,"children":1411},{"__ignoreMap":7},[1412,1420,1428,1436,1444,1452,1460,1468,1475,1483],{"type":14,"tag":164,"props":1413,"children":1414},{"class":166,"line":167},[1415],{"type":14,"tag":164,"props":1416,"children":1417},{},[1418],{"type":20,"value":1419},"# Log camera intrinsics once (static)\n",{"type":14,"tag":164,"props":1421,"children":1422},{"class":166,"line":313},[1423],{"type":14,"tag":164,"props":1424,"children":1425},{},[1426],{"type":20,"value":1427},"rr.log(\"robot\u002Fcamera\", rr.Pinhole(\n",{"type":14,"tag":164,"props":1429,"children":1430},{"class":166,"line":323},[1431],{"type":14,"tag":164,"props":1432,"children":1433},{},[1434],{"type":20,"value":1435},"    focal_length=[fx, fy],\n",{"type":14,"tag":164,"props":1437,"children":1438},{"class":166,"line":332},[1439],{"type":14,"tag":164,"props":1440,"children":1441},{},[1442],{"type":20,"value":1443},"    principal_point=[cx, cy],\n",{"type":14,"tag":164,"props":1445,"children":1446},{"class":166,"line":341},[1447],{"type":14,"tag":164,"props":1448,"children":1449},{},[1450],{"type":20,"value":1451},"    width=640,\n",{"type":14,"tag":164,"props":1453,"children":1454},{"class":166,"line":349},[1455],{"type":14,"tag":164,"props":1456,"children":1457},{},[1458],{"type":20,"value":1459},"    height=480\n",{"type":14,"tag":164,"props":1461,"children":1462},{"class":166,"line":358},[1463],{"type":14,"tag":164,"props":1464,"children":1465},{},[1466],{"type":20,"value":1467},"), static=True)\n",{"type":14,"tag":164,"props":1469,"children":1470},{"class":166,"line":367},[1471],{"type":14,"tag":164,"props":1472,"children":1473},{"emptyLinePlaceholder":317},[1474],{"type":20,"value":320},{"type":14,"tag":164,"props":1476,"children":1477},{"class":166,"line":375},[1478],{"type":14,"tag":164,"props":1479,"children":1480},{},[1481],{"type":20,"value":1482},"# Log images on the same entity\n",{"type":14,"tag":164,"props":1484,"children":1485},{"class":166,"line":384},[1486],{"type":14,"tag":164,"props":1487,"children":1488},{},[1489],{"type":20,"value":1490},"rr.log(\"robot\u002Fcamera\", rr.Image(frame))\n",{"type":14,"tag":46,"props":1492,"children":1493},{},[],{"type":14,"tag":50,"props":1495,"children":1497},{"id":1496},"logging-scalar-metrics",[1498],{"type":20,"value":1499},"Logging Scalar Metrics",{"type":14,"tag":22,"props":1501,"children":1502},{},[1503],{"type":20,"value":1504},"Scalars are single numeric values over time. Perfect for training metrics, sensor readings, and system stats.",{"type":14,"tag":62,"props":1506,"children":1508},{"code":1507,"language":145,"meta":7,"className":202,"style":7},"# Training metrics\nrr.set_time(\"epoch\", sequence=epoch)\nrr.log(\"train\u002Floss\", rr.Scalars(loss))\nrr.log(\"train\u002Faccuracy\", rr.Scalars(accuracy))\nrr.log(\"train\u002Flearning_rate\", rr.Scalars(lr))\n\n# Robot sensors\nrr.set_time(\"frame\", sequence=frame)\nrr.log(\"robot\u002Fbattery\", rr.Scalars(battery_pct))\nrr.log(\"robot\u002Fspeed\", rr.Scalars(speed_ms))\nrr.log(\"robot\u002Ftemperature\", rr.Scalars(motor_temp))\n",[1509],{"type":14,"tag":67,"props":1510,"children":1511},{"__ignoreMap":7},[1512,1520,1528,1536,1544,1552,1559,1567,1575,1583,1591],{"type":14,"tag":164,"props":1513,"children":1514},{"class":166,"line":167},[1515],{"type":14,"tag":164,"props":1516,"children":1517},{},[1518],{"type":20,"value":1519},"# Training metrics\n",{"type":14,"tag":164,"props":1521,"children":1522},{"class":166,"line":313},[1523],{"type":14,"tag":164,"props":1524,"children":1525},{},[1526],{"type":20,"value":1527},"rr.set_time(\"epoch\", sequence=epoch)\n",{"type":14,"tag":164,"props":1529,"children":1530},{"class":166,"line":323},[1531],{"type":14,"tag":164,"props":1532,"children":1533},{},[1534],{"type":20,"value":1535},"rr.log(\"train\u002Floss\", rr.Scalars(loss))\n",{"type":14,"tag":164,"props":1537,"children":1538},{"class":166,"line":332},[1539],{"type":14,"tag":164,"props":1540,"children":1541},{},[1542],{"type":20,"value":1543},"rr.log(\"train\u002Faccuracy\", rr.Scalars(accuracy))\n",{"type":14,"tag":164,"props":1545,"children":1546},{"class":166,"line":341},[1547],{"type":14,"tag":164,"props":1548,"children":1549},{},[1550],{"type":20,"value":1551},"rr.log(\"train\u002Flearning_rate\", rr.Scalars(lr))\n",{"type":14,"tag":164,"props":1553,"children":1554},{"class":166,"line":349},[1555],{"type":14,"tag":164,"props":1556,"children":1557},{"emptyLinePlaceholder":317},[1558],{"type":20,"value":320},{"type":14,"tag":164,"props":1560,"children":1561},{"class":166,"line":358},[1562],{"type":14,"tag":164,"props":1563,"children":1564},{},[1565],{"type":20,"value":1566},"# Robot sensors\n",{"type":14,"tag":164,"props":1568,"children":1569},{"class":166,"line":367},[1570],{"type":14,"tag":164,"props":1571,"children":1572},{},[1573],{"type":20,"value":1574},"rr.set_time(\"frame\", sequence=frame)\n",{"type":14,"tag":164,"props":1576,"children":1577},{"class":166,"line":375},[1578],{"type":14,"tag":164,"props":1579,"children":1580},{},[1581],{"type":20,"value":1582},"rr.log(\"robot\u002Fbattery\", rr.Scalars(battery_pct))\n",{"type":14,"tag":164,"props":1584,"children":1585},{"class":166,"line":384},[1586],{"type":14,"tag":164,"props":1587,"children":1588},{},[1589],{"type":20,"value":1590},"rr.log(\"robot\u002Fspeed\", rr.Scalars(speed_ms))\n",{"type":14,"tag":164,"props":1592,"children":1593},{"class":166,"line":485},[1594],{"type":14,"tag":164,"props":1595,"children":1596},{},[1597],{"type":20,"value":1598},"rr.log(\"robot\u002Ftemperature\", rr.Scalars(motor_temp))\n",{"type":14,"tag":22,"props":1600,"children":1601},{},[1602],{"type":20,"value":1603},"The viewer plots these as line charts automatically. You can view multiple scalars on the same chart by selecting them together.",{"type":14,"tag":46,"props":1605,"children":1606},{},[],{"type":14,"tag":50,"props":1608,"children":1610},{"id":1609},"logging-text-and-events",[1611],{"type":20,"value":1612},"Logging Text and Events",{"type":14,"tag":143,"props":1614,"children":1616},{"id":1615},"text-logs",[1617],{"type":20,"value":1618},"Text Logs",{"type":14,"tag":22,"props":1620,"children":1621},{},[1622],{"type":20,"value":1623},"Use text logs to record events, warnings, and errors alongside your data:",{"type":14,"tag":62,"props":1625,"children":1627},{"code":1626,"language":145,"meta":7,"className":202,"style":7},"rr.log(\"logs\u002Fsystem\", rr.TextLog(\"Connected to cluster\", level=rr.TextLogLevel.INFO))\nrr.log(\"logs\u002Fsystem\", rr.TextLog(\"High memory usage: 87%\", level=rr.TextLogLevel.WARN))\nrr.log(\"logs\u002Fsystem\", rr.TextLog(\"Motor fault on joint 3\", level=rr.TextLogLevel.ERROR))\nrr.log(\"logs\u002Frobot\", rr.TextLog(\"Reached waypoint 5\"))\n",[1628],{"type":14,"tag":67,"props":1629,"children":1630},{"__ignoreMap":7},[1631,1639,1647,1655],{"type":14,"tag":164,"props":1632,"children":1633},{"class":166,"line":167},[1634],{"type":14,"tag":164,"props":1635,"children":1636},{},[1637],{"type":20,"value":1638},"rr.log(\"logs\u002Fsystem\", rr.TextLog(\"Connected to cluster\", level=rr.TextLogLevel.INFO))\n",{"type":14,"tag":164,"props":1640,"children":1641},{"class":166,"line":313},[1642],{"type":14,"tag":164,"props":1643,"children":1644},{},[1645],{"type":20,"value":1646},"rr.log(\"logs\u002Fsystem\", rr.TextLog(\"High memory usage: 87%\", level=rr.TextLogLevel.WARN))\n",{"type":14,"tag":164,"props":1648,"children":1649},{"class":166,"line":323},[1650],{"type":14,"tag":164,"props":1651,"children":1652},{},[1653],{"type":20,"value":1654},"rr.log(\"logs\u002Fsystem\", rr.TextLog(\"Motor fault on joint 3\", level=rr.TextLogLevel.ERROR))\n",{"type":14,"tag":164,"props":1656,"children":1657},{"class":166,"line":332},[1658],{"type":14,"tag":164,"props":1659,"children":1660},{},[1661],{"type":20,"value":1662},"rr.log(\"logs\u002Frobot\", rr.TextLog(\"Reached waypoint 5\"))\n",{"type":14,"tag":22,"props":1664,"children":1665},{},[1666],{"type":20,"value":1667},"Text logs appear in the viewer's log panel and are synchronized with the timeline, so you can see exactly what was happening when an event occurred.",{"type":14,"tag":143,"props":1669,"children":1671},{"id":1670},"rich-text-documents",[1672],{"type":20,"value":1673},"Rich Text Documents",{"type":14,"tag":22,"props":1675,"children":1676},{},[1677],{"type":20,"value":1678},"For longer content like reports or markdown:",{"type":14,"tag":62,"props":1680,"children":1682},{"code":1681,"language":145,"meta":7,"className":202,"style":7},"rr.log(\"docs\u002Fsummary\", rr.TextDocument(\n    \"## Run Summary\\n\\nAll systems nominal.\\n\\n- Battery: 87%\\n- Speed: 1.2 m\u002Fs\",\n    media_type=\"text\u002Fmarkdown\"\n))\n",[1683],{"type":14,"tag":67,"props":1684,"children":1685},{"__ignoreMap":7},[1686,1694,1702,1710],{"type":14,"tag":164,"props":1687,"children":1688},{"class":166,"line":167},[1689],{"type":14,"tag":164,"props":1690,"children":1691},{},[1692],{"type":20,"value":1693},"rr.log(\"docs\u002Fsummary\", rr.TextDocument(\n",{"type":14,"tag":164,"props":1695,"children":1696},{"class":166,"line":313},[1697],{"type":14,"tag":164,"props":1698,"children":1699},{},[1700],{"type":20,"value":1701},"    \"## Run Summary\\n\\nAll systems nominal.\\n\\n- Battery: 87%\\n- Speed: 1.2 m\u002Fs\",\n",{"type":14,"tag":164,"props":1703,"children":1704},{"class":166,"line":323},[1705],{"type":14,"tag":164,"props":1706,"children":1707},{},[1708],{"type":20,"value":1709},"    media_type=\"text\u002Fmarkdown\"\n",{"type":14,"tag":164,"props":1711,"children":1712},{"class":166,"line":332},[1713],{"type":14,"tag":164,"props":1714,"children":1715},{},[1716],{"type":20,"value":875},{"type":14,"tag":46,"props":1718,"children":1719},{},[],{"type":14,"tag":50,"props":1721,"children":1723},{"id":1722},"logging-gps-and-geographic-data",[1724],{"type":20,"value":1725},"Logging GPS and Geographic Data",{"type":14,"tag":22,"props":1727,"children":1728},{},[1729],{"type":20,"value":1730},"If your robots operate outdoors, you can log GPS coordinates and see them on a map in the viewer.",{"type":14,"tag":62,"props":1732,"children":1734},{"code":1733,"language":145,"meta":7,"className":202,"style":7},"# A single GPS position\nrr.log(\"robot\u002Fgps\", rr.GeoPoints(\n    lat_lon=[[-1.286389, 36.817223]],  # latitude, longitude\n    radii=10.0\n))\n\n# A GPS track (path the robot has taken)\nrr.log(\"robot\u002Fpath\", rr.GeoLineStrings(\n    lat_lon=[[\n        [-1.286, 36.817],\n        [-1.290, 36.820],\n        [-1.295, 36.825],\n        [-1.300, 36.830],\n    ]]\n))\n",[1735],{"type":14,"tag":67,"props":1736,"children":1737},{"__ignoreMap":7},[1738,1746,1754,1762,1770,1777,1784,1792,1800,1808,1816,1824,1832,1840,1848],{"type":14,"tag":164,"props":1739,"children":1740},{"class":166,"line":167},[1741],{"type":14,"tag":164,"props":1742,"children":1743},{},[1744],{"type":20,"value":1745},"# A single GPS position\n",{"type":14,"tag":164,"props":1747,"children":1748},{"class":166,"line":313},[1749],{"type":14,"tag":164,"props":1750,"children":1751},{},[1752],{"type":20,"value":1753},"rr.log(\"robot\u002Fgps\", rr.GeoPoints(\n",{"type":14,"tag":164,"props":1755,"children":1756},{"class":166,"line":323},[1757],{"type":14,"tag":164,"props":1758,"children":1759},{},[1760],{"type":20,"value":1761},"    lat_lon=[[-1.286389, 36.817223]],  # latitude, longitude\n",{"type":14,"tag":164,"props":1763,"children":1764},{"class":166,"line":332},[1765],{"type":14,"tag":164,"props":1766,"children":1767},{},[1768],{"type":20,"value":1769},"    radii=10.0\n",{"type":14,"tag":164,"props":1771,"children":1772},{"class":166,"line":341},[1773],{"type":14,"tag":164,"props":1774,"children":1775},{},[1776],{"type":20,"value":875},{"type":14,"tag":164,"props":1778,"children":1779},{"class":166,"line":349},[1780],{"type":14,"tag":164,"props":1781,"children":1782},{"emptyLinePlaceholder":317},[1783],{"type":20,"value":320},{"type":14,"tag":164,"props":1785,"children":1786},{"class":166,"line":358},[1787],{"type":14,"tag":164,"props":1788,"children":1789},{},[1790],{"type":20,"value":1791},"# A GPS track (path the robot has taken)\n",{"type":14,"tag":164,"props":1793,"children":1794},{"class":166,"line":367},[1795],{"type":14,"tag":164,"props":1796,"children":1797},{},[1798],{"type":20,"value":1799},"rr.log(\"robot\u002Fpath\", rr.GeoLineStrings(\n",{"type":14,"tag":164,"props":1801,"children":1802},{"class":166,"line":375},[1803],{"type":14,"tag":164,"props":1804,"children":1805},{},[1806],{"type":20,"value":1807},"    lat_lon=[[\n",{"type":14,"tag":164,"props":1809,"children":1810},{"class":166,"line":384},[1811],{"type":14,"tag":164,"props":1812,"children":1813},{},[1814],{"type":20,"value":1815},"        [-1.286, 36.817],\n",{"type":14,"tag":164,"props":1817,"children":1818},{"class":166,"line":485},[1819],{"type":14,"tag":164,"props":1820,"children":1821},{},[1822],{"type":20,"value":1823},"        [-1.290, 36.820],\n",{"type":14,"tag":164,"props":1825,"children":1826},{"class":166,"line":494},[1827],{"type":14,"tag":164,"props":1828,"children":1829},{},[1830],{"type":20,"value":1831},"        [-1.295, 36.825],\n",{"type":14,"tag":164,"props":1833,"children":1834},{"class":166,"line":503},[1835],{"type":14,"tag":164,"props":1836,"children":1837},{},[1838],{"type":20,"value":1839},"        [-1.300, 36.830],\n",{"type":14,"tag":164,"props":1841,"children":1842},{"class":166,"line":512},[1843],{"type":14,"tag":164,"props":1844,"children":1845},{},[1846],{"type":20,"value":1847},"    ]]\n",{"type":14,"tag":164,"props":1849,"children":1851},{"class":166,"line":1850},15,[1852],{"type":14,"tag":164,"props":1853,"children":1854},{},[1855],{"type":20,"value":875},{"type":14,"tag":46,"props":1857,"children":1858},{},[],{"type":14,"tag":50,"props":1860,"children":1862},{"id":1861},"logging-graphs-and-networks",[1863],{"type":20,"value":1864},"Logging Graphs and Networks",{"type":14,"tag":22,"props":1866,"children":1867},{},[1868],{"type":20,"value":1869},"Useful for visualizing pipeline dependencies, neural network architectures, or any graph-structured data:",{"type":14,"tag":62,"props":1871,"children":1873},{"code":1872,"language":145,"meta":7,"className":202,"style":7},"rr.log(\"pipeline\u002Fgraph\", rr.GraphNodes(\n    node_ids=[\"input\", \"conv1\", \"relu1\", \"conv2\", \"relu2\", \"output\"],\n    labels=[\"Input\", \"Conv 3x3\", \"ReLU\", \"Conv 3x3\", \"ReLU\", \"Output\"]\n))\n\nrr.log(\"pipeline\u002Fgraph\", rr.GraphEdges(\n    edges=[\n        (\"input\", \"conv1\"),\n        (\"conv1\", \"relu1\"),\n        (\"relu1\", \"conv2\"),\n        (\"conv2\", \"relu2\"),\n        (\"relu2\", \"output\"),\n    ]\n))\n",[1874],{"type":14,"tag":67,"props":1875,"children":1876},{"__ignoreMap":7},[1877,1885,1893,1901,1908,1915,1923,1931,1939,1947,1955,1963,1971,1979],{"type":14,"tag":164,"props":1878,"children":1879},{"class":166,"line":167},[1880],{"type":14,"tag":164,"props":1881,"children":1882},{},[1883],{"type":20,"value":1884},"rr.log(\"pipeline\u002Fgraph\", rr.GraphNodes(\n",{"type":14,"tag":164,"props":1886,"children":1887},{"class":166,"line":313},[1888],{"type":14,"tag":164,"props":1889,"children":1890},{},[1891],{"type":20,"value":1892},"    node_ids=[\"input\", \"conv1\", \"relu1\", \"conv2\", \"relu2\", \"output\"],\n",{"type":14,"tag":164,"props":1894,"children":1895},{"class":166,"line":323},[1896],{"type":14,"tag":164,"props":1897,"children":1898},{},[1899],{"type":20,"value":1900},"    labels=[\"Input\", \"Conv 3x3\", \"ReLU\", \"Conv 3x3\", \"ReLU\", \"Output\"]\n",{"type":14,"tag":164,"props":1902,"children":1903},{"class":166,"line":332},[1904],{"type":14,"tag":164,"props":1905,"children":1906},{},[1907],{"type":20,"value":875},{"type":14,"tag":164,"props":1909,"children":1910},{"class":166,"line":341},[1911],{"type":14,"tag":164,"props":1912,"children":1913},{"emptyLinePlaceholder":317},[1914],{"type":20,"value":320},{"type":14,"tag":164,"props":1916,"children":1917},{"class":166,"line":349},[1918],{"type":14,"tag":164,"props":1919,"children":1920},{},[1921],{"type":20,"value":1922},"rr.log(\"pipeline\u002Fgraph\", rr.GraphEdges(\n",{"type":14,"tag":164,"props":1924,"children":1925},{"class":166,"line":358},[1926],{"type":14,"tag":164,"props":1927,"children":1928},{},[1929],{"type":20,"value":1930},"    edges=[\n",{"type":14,"tag":164,"props":1932,"children":1933},{"class":166,"line":367},[1934],{"type":14,"tag":164,"props":1935,"children":1936},{},[1937],{"type":20,"value":1938},"        (\"input\", \"conv1\"),\n",{"type":14,"tag":164,"props":1940,"children":1941},{"class":166,"line":375},[1942],{"type":14,"tag":164,"props":1943,"children":1944},{},[1945],{"type":20,"value":1946},"        (\"conv1\", \"relu1\"),\n",{"type":14,"tag":164,"props":1948,"children":1949},{"class":166,"line":384},[1950],{"type":14,"tag":164,"props":1951,"children":1952},{},[1953],{"type":20,"value":1954},"        (\"relu1\", \"conv2\"),\n",{"type":14,"tag":164,"props":1956,"children":1957},{"class":166,"line":485},[1958],{"type":14,"tag":164,"props":1959,"children":1960},{},[1961],{"type":20,"value":1962},"        (\"conv2\", \"relu2\"),\n",{"type":14,"tag":164,"props":1964,"children":1965},{"class":166,"line":494},[1966],{"type":14,"tag":164,"props":1967,"children":1968},{},[1969],{"type":20,"value":1970},"        (\"relu2\", \"output\"),\n",{"type":14,"tag":164,"props":1972,"children":1973},{"class":166,"line":503},[1974],{"type":14,"tag":164,"props":1975,"children":1976},{},[1977],{"type":20,"value":1978},"    ]\n",{"type":14,"tag":164,"props":1980,"children":1981},{"class":166,"line":512},[1982],{"type":14,"tag":164,"props":1983,"children":1984},{},[1985],{"type":20,"value":875},{"type":14,"tag":46,"props":1987,"children":1988},{},[],{"type":14,"tag":50,"props":1990,"children":1992},{"id":1991},"embedding-the-viewer-in-react",[1993],{"type":20,"value":1994},"Embedding the Viewer in React",{"type":14,"tag":22,"props":1996,"children":1997},{},[1998],{"type":20,"value":1999},"If you want to embed the visualization viewer directly in your CredVault dashboard or web app, use the React component:",{"type":14,"tag":62,"props":2001,"children":2005},{"code":2002,"language":2003,"meta":7,"className":2004,"style":7},"import { WebViewer } from \"@credvault\u002Frerun-viewer-react\"\n\nexport default function RobotDashboard() {\n  return (\n    \u003Cdiv style={{ width: \"100%\", height: \"600px\" }}>\n      \u003CWebViewer\n        width=\"100%\"\n        height=\"600px\"\n        rrd=\"https:\u002F\u002Fcredvault-production.up.railway.app\u002Fapi\u002Frerun\u002Frecording\u002Fabc123\"\n      \u002F>\n    \u003C\u002Fdiv>\n  )\n}\n","jsx","language-jsx shiki shiki-themes github-dark",[2006],{"type":14,"tag":67,"props":2007,"children":2008},{"__ignoreMap":7},[2009,2034,2041,2069,2082,2131,2145,2162,2179,2196,2204,2221,2229],{"type":14,"tag":164,"props":2010,"children":2011},{"class":166,"line":167},[2012,2018,2024,2029],{"type":14,"tag":164,"props":2013,"children":2015},{"style":2014},"--shiki-default:#F97583",[2016],{"type":20,"value":2017},"import",{"type":14,"tag":164,"props":2019,"children":2021},{"style":2020},"--shiki-default:#E1E4E8",[2022],{"type":20,"value":2023}," { WebViewer } ",{"type":14,"tag":164,"props":2025,"children":2026},{"style":2014},[2027],{"type":20,"value":2028},"from",{"type":14,"tag":164,"props":2030,"children":2031},{"style":177},[2032],{"type":20,"value":2033}," \"@credvault\u002Frerun-viewer-react\"\n",{"type":14,"tag":164,"props":2035,"children":2036},{"class":166,"line":313},[2037],{"type":14,"tag":164,"props":2038,"children":2039},{"emptyLinePlaceholder":317},[2040],{"type":20,"value":320},{"type":14,"tag":164,"props":2042,"children":2043},{"class":166,"line":323},[2044,2049,2054,2059,2064],{"type":14,"tag":164,"props":2045,"children":2046},{"style":2014},[2047],{"type":20,"value":2048},"export",{"type":14,"tag":164,"props":2050,"children":2051},{"style":2014},[2052],{"type":20,"value":2053}," default",{"type":14,"tag":164,"props":2055,"children":2056},{"style":2014},[2057],{"type":20,"value":2058}," function",{"type":14,"tag":164,"props":2060,"children":2061},{"style":171},[2062],{"type":20,"value":2063}," RobotDashboard",{"type":14,"tag":164,"props":2065,"children":2066},{"style":2020},[2067],{"type":20,"value":2068},"() {\n",{"type":14,"tag":164,"props":2070,"children":2071},{"class":166,"line":332},[2072,2077],{"type":14,"tag":164,"props":2073,"children":2074},{"style":2014},[2075],{"type":20,"value":2076},"  return",{"type":14,"tag":164,"props":2078,"children":2079},{"style":2020},[2080],{"type":20,"value":2081}," (\n",{"type":14,"tag":164,"props":2083,"children":2084},{"class":166,"line":341},[2085,2090,2096,2101,2106,2111,2116,2121,2126],{"type":14,"tag":164,"props":2086,"children":2087},{"style":2020},[2088],{"type":20,"value":2089},"    \u003C",{"type":14,"tag":164,"props":2091,"children":2093},{"style":2092},"--shiki-default:#85E89D",[2094],{"type":20,"value":2095},"div",{"type":14,"tag":164,"props":2097,"children":2098},{"style":171},[2099],{"type":20,"value":2100}," style",{"type":14,"tag":164,"props":2102,"children":2103},{"style":2014},[2104],{"type":20,"value":2105},"=",{"type":14,"tag":164,"props":2107,"children":2108},{"style":2020},[2109],{"type":20,"value":2110},"{{ width: ",{"type":14,"tag":164,"props":2112,"children":2113},{"style":177},[2114],{"type":20,"value":2115},"\"100%\"",{"type":14,"tag":164,"props":2117,"children":2118},{"style":2020},[2119],{"type":20,"value":2120},", height: ",{"type":14,"tag":164,"props":2122,"children":2123},{"style":177},[2124],{"type":20,"value":2125},"\"600px\"",{"type":14,"tag":164,"props":2127,"children":2128},{"style":2020},[2129],{"type":20,"value":2130}," }}>\n",{"type":14,"tag":164,"props":2132,"children":2133},{"class":166,"line":349},[2134,2139],{"type":14,"tag":164,"props":2135,"children":2136},{"style":2020},[2137],{"type":20,"value":2138},"      \u003C",{"type":14,"tag":164,"props":2140,"children":2142},{"style":2141},"--shiki-default:#79B8FF",[2143],{"type":20,"value":2144},"WebViewer\n",{"type":14,"tag":164,"props":2146,"children":2147},{"class":166,"line":358},[2148,2153,2157],{"type":14,"tag":164,"props":2149,"children":2150},{"style":171},[2151],{"type":20,"value":2152},"        width",{"type":14,"tag":164,"props":2154,"children":2155},{"style":2014},[2156],{"type":20,"value":2105},{"type":14,"tag":164,"props":2158,"children":2159},{"style":177},[2160],{"type":20,"value":2161},"\"100%\"\n",{"type":14,"tag":164,"props":2163,"children":2164},{"class":166,"line":367},[2165,2170,2174],{"type":14,"tag":164,"props":2166,"children":2167},{"style":171},[2168],{"type":20,"value":2169},"        height",{"type":14,"tag":164,"props":2171,"children":2172},{"style":2014},[2173],{"type":20,"value":2105},{"type":14,"tag":164,"props":2175,"children":2176},{"style":177},[2177],{"type":20,"value":2178},"\"600px\"\n",{"type":14,"tag":164,"props":2180,"children":2181},{"class":166,"line":375},[2182,2187,2191],{"type":14,"tag":164,"props":2183,"children":2184},{"style":171},[2185],{"type":20,"value":2186},"        rrd",{"type":14,"tag":164,"props":2188,"children":2189},{"style":2014},[2190],{"type":20,"value":2105},{"type":14,"tag":164,"props":2192,"children":2193},{"style":177},[2194],{"type":20,"value":2195},"\"https:\u002F\u002Fcredvault-production.up.railway.app\u002Fapi\u002Frerun\u002Frecording\u002Fabc123\"\n",{"type":14,"tag":164,"props":2197,"children":2198},{"class":166,"line":384},[2199],{"type":14,"tag":164,"props":2200,"children":2201},{"style":2020},[2202],{"type":20,"value":2203},"      \u002F>\n",{"type":14,"tag":164,"props":2205,"children":2206},{"class":166,"line":485},[2207,2212,2216],{"type":14,"tag":164,"props":2208,"children":2209},{"style":2020},[2210],{"type":20,"value":2211},"    \u003C\u002F",{"type":14,"tag":164,"props":2213,"children":2214},{"style":2092},[2215],{"type":20,"value":2095},{"type":14,"tag":164,"props":2217,"children":2218},{"style":2020},[2219],{"type":20,"value":2220},">\n",{"type":14,"tag":164,"props":2222,"children":2223},{"class":166,"line":494},[2224],{"type":14,"tag":164,"props":2225,"children":2226},{"style":2020},[2227],{"type":20,"value":2228},"  )\n",{"type":14,"tag":164,"props":2230,"children":2231},{"class":166,"line":503},[2232],{"type":14,"tag":164,"props":2233,"children":2234},{"style":2020},[2235],{"type":20,"value":2236},"}\n",{"type":14,"tag":22,"props":2238,"children":2239},{},[2240,2242,2248,2250,2256,2258,2264],{"type":20,"value":2241},"The ",{"type":14,"tag":67,"props":2243,"children":2245},{"className":2244},[],[2246],{"type":20,"value":2247},"rrd",{"type":20,"value":2249}," prop accepts a URL to a ",{"type":14,"tag":67,"props":2251,"children":2253},{"className":2252},[],[2254],{"type":20,"value":2255},".rrd",{"type":20,"value":2257}," recording file. You can generate these from Python using ",{"type":14,"tag":67,"props":2259,"children":2261},{"className":2260},[],[2262],{"type":20,"value":2263},"rr.save(\"recording.rrd\")",{"type":20,"value":2265}," and then serve them from your backend.",{"type":14,"tag":46,"props":2267,"children":2268},{},[],{"type":14,"tag":50,"props":2270,"children":2272},{"id":2271},"complete-example-robot-telemetry",[2273],{"type":20,"value":2274},"Complete Example: Robot Telemetry",{"type":14,"tag":22,"props":2276,"children":2277},{},[2278],{"type":20,"value":2279},"Here's a complete example that logs everything you'd want from a mobile robot:",{"type":14,"tag":62,"props":2281,"children":2283},{"code":2282,"language":145,"meta":7,"className":202,"style":7},"import rerun as rr\nimport numpy as np\nimport time\n\nrr.init(\"robot_telemetry\")\nrr.spawn()\n\n# Log static camera calibration once\nrr.log(\"robot\u002Fcamera\", rr.Pinhole(\n    focal_length=500, width=640, height=480\n), static=True)\n\nframe = 0\nwhile True:\n    rr.set_time(\"frame\", sequence=frame)\n\n    # Robot position and orientation\n    x = frame * 0.01\n    y = np.sin(frame * 0.05) * 2\n    yaw = frame * 0.02\n    rr.log(\"robot\u002Ftransform\", rr.Transform3D(\n        translation=[x, y, 0],\n        rotation=rr.Quaternion(xyzw=[0, 0, np.sin(yaw\u002F2), np.cos(yaw\u002F2)])\n    ))\n\n    # Camera image\n    rr.log(\"robot\u002Fcamera\", rr.Image(get_camera_frame()))\n\n    # Lidar scan\n    lidar_points = get_lidar_scan()\n    rr.log(\"robot\u002Flidar\", rr.Points3D(positions=lidar_points, radii=0.02))\n\n    # Sensor readings\n    rr.log(\"robot\u002Fbattery\", rr.Scalars(get_battery_level()))\n    rr.log(\"robot\u002Fspeed\", rr.Scalars(get_speed()))\n    rr.log(\"robot\u002Fmotor_temp\", rr.Scalars(get_motor_temperature()))\n\n    # Status log\n    rr.log(\"robot\u002Flogs\", rr.TextLog(f\"Frame {frame}: position ({x:.2f}, {y:.2f})\"))\n\n    frame += 1\n    time.sleep(0.05)  # 20 fps\n",[2284],{"type":14,"tag":67,"props":2285,"children":2286},{"__ignoreMap":7},[2287,2294,2301,2308,2315,2323,2330,2337,2345,2352,2360,2367,2374,2382,2390,2397,2405,2414,2423,2432,2441,2450,2459,2468,2477,2485,2494,2503,2511,2520,2529,2538,2546,2555,2564,2573,2582,2590,2599,2608,2616,2625],{"type":14,"tag":164,"props":2288,"children":2289},{"class":166,"line":167},[2290],{"type":14,"tag":164,"props":2291,"children":2292},{},[2293],{"type":20,"value":201},{"type":14,"tag":164,"props":2295,"children":2296},{"class":166,"line":313},[2297],{"type":14,"tag":164,"props":2298,"children":2299},{},[2300],{"type":20,"value":422},{"type":14,"tag":164,"props":2302,"children":2303},{"class":166,"line":323},[2304],{"type":14,"tag":164,"props":2305,"children":2306},{},[2307],{"type":20,"value":692},{"type":14,"tag":164,"props":2309,"children":2310},{"class":166,"line":332},[2311],{"type":14,"tag":164,"props":2312,"children":2313},{"emptyLinePlaceholder":317},[2314],{"type":20,"value":320},{"type":14,"tag":164,"props":2316,"children":2317},{"class":166,"line":341},[2318],{"type":14,"tag":164,"props":2319,"children":2320},{},[2321],{"type":20,"value":2322},"rr.init(\"robot_telemetry\")\n",{"type":14,"tag":164,"props":2324,"children":2325},{"class":166,"line":349},[2326],{"type":14,"tag":164,"props":2327,"children":2328},{},[2329],{"type":20,"value":364},{"type":14,"tag":164,"props":2331,"children":2332},{"class":166,"line":358},[2333],{"type":14,"tag":164,"props":2334,"children":2335},{"emptyLinePlaceholder":317},[2336],{"type":20,"value":320},{"type":14,"tag":164,"props":2338,"children":2339},{"class":166,"line":367},[2340],{"type":14,"tag":164,"props":2341,"children":2342},{},[2343],{"type":20,"value":2344},"# Log static camera calibration once\n",{"type":14,"tag":164,"props":2346,"children":2347},{"class":166,"line":375},[2348],{"type":14,"tag":164,"props":2349,"children":2350},{},[2351],{"type":20,"value":1427},{"type":14,"tag":164,"props":2353,"children":2354},{"class":166,"line":384},[2355],{"type":14,"tag":164,"props":2356,"children":2357},{},[2358],{"type":20,"value":2359},"    focal_length=500, width=640, height=480\n",{"type":14,"tag":164,"props":2361,"children":2362},{"class":166,"line":485},[2363],{"type":14,"tag":164,"props":2364,"children":2365},{},[2366],{"type":20,"value":1467},{"type":14,"tag":164,"props":2368,"children":2369},{"class":166,"line":494},[2370],{"type":14,"tag":164,"props":2371,"children":2372},{"emptyLinePlaceholder":317},[2373],{"type":20,"value":320},{"type":14,"tag":164,"props":2375,"children":2376},{"class":166,"line":503},[2377],{"type":14,"tag":164,"props":2378,"children":2379},{},[2380],{"type":20,"value":2381},"frame = 0\n",{"type":14,"tag":164,"props":2383,"children":2384},{"class":166,"line":512},[2385],{"type":14,"tag":164,"props":2386,"children":2387},{},[2388],{"type":20,"value":2389},"while True:\n",{"type":14,"tag":164,"props":2391,"children":2392},{"class":166,"line":1850},[2393],{"type":14,"tag":164,"props":2394,"children":2395},{},[2396],{"type":20,"value":475},{"type":14,"tag":164,"props":2398,"children":2400},{"class":166,"line":2399},16,[2401],{"type":14,"tag":164,"props":2402,"children":2403},{"emptyLinePlaceholder":317},[2404],{"type":20,"value":320},{"type":14,"tag":164,"props":2406,"children":2408},{"class":166,"line":2407},17,[2409],{"type":14,"tag":164,"props":2410,"children":2411},{},[2412],{"type":20,"value":2413},"    # Robot position and orientation\n",{"type":14,"tag":164,"props":2415,"children":2417},{"class":166,"line":2416},18,[2418],{"type":14,"tag":164,"props":2419,"children":2420},{},[2421],{"type":20,"value":2422},"    x = frame * 0.01\n",{"type":14,"tag":164,"props":2424,"children":2426},{"class":166,"line":2425},19,[2427],{"type":14,"tag":164,"props":2428,"children":2429},{},[2430],{"type":20,"value":2431},"    y = np.sin(frame * 0.05) * 2\n",{"type":14,"tag":164,"props":2433,"children":2435},{"class":166,"line":2434},20,[2436],{"type":14,"tag":164,"props":2437,"children":2438},{},[2439],{"type":20,"value":2440},"    yaw = frame * 0.02\n",{"type":14,"tag":164,"props":2442,"children":2444},{"class":166,"line":2443},21,[2445],{"type":14,"tag":164,"props":2446,"children":2447},{},[2448],{"type":20,"value":2449},"    rr.log(\"robot\u002Ftransform\", rr.Transform3D(\n",{"type":14,"tag":164,"props":2451,"children":2453},{"class":166,"line":2452},22,[2454],{"type":14,"tag":164,"props":2455,"children":2456},{},[2457],{"type":20,"value":2458},"        translation=[x, y, 0],\n",{"type":14,"tag":164,"props":2460,"children":2462},{"class":166,"line":2461},23,[2463],{"type":14,"tag":164,"props":2464,"children":2465},{},[2466],{"type":20,"value":2467},"        rotation=rr.Quaternion(xyzw=[0, 0, np.sin(yaw\u002F2), np.cos(yaw\u002F2)])\n",{"type":14,"tag":164,"props":2469,"children":2471},{"class":166,"line":2470},24,[2472],{"type":14,"tag":164,"props":2473,"children":2474},{},[2475],{"type":20,"value":2476},"    ))\n",{"type":14,"tag":164,"props":2478,"children":2480},{"class":166,"line":2479},25,[2481],{"type":14,"tag":164,"props":2482,"children":2483},{"emptyLinePlaceholder":317},[2484],{"type":20,"value":320},{"type":14,"tag":164,"props":2486,"children":2488},{"class":166,"line":2487},26,[2489],{"type":14,"tag":164,"props":2490,"children":2491},{},[2492],{"type":20,"value":2493},"    # Camera image\n",{"type":14,"tag":164,"props":2495,"children":2497},{"class":166,"line":2496},27,[2498],{"type":14,"tag":164,"props":2499,"children":2500},{},[2501],{"type":20,"value":2502},"    rr.log(\"robot\u002Fcamera\", rr.Image(get_camera_frame()))\n",{"type":14,"tag":164,"props":2504,"children":2506},{"class":166,"line":2505},28,[2507],{"type":14,"tag":164,"props":2508,"children":2509},{"emptyLinePlaceholder":317},[2510],{"type":20,"value":320},{"type":14,"tag":164,"props":2512,"children":2514},{"class":166,"line":2513},29,[2515],{"type":14,"tag":164,"props":2516,"children":2517},{},[2518],{"type":20,"value":2519},"    # Lidar scan\n",{"type":14,"tag":164,"props":2521,"children":2523},{"class":166,"line":2522},30,[2524],{"type":14,"tag":164,"props":2525,"children":2526},{},[2527],{"type":20,"value":2528},"    lidar_points = get_lidar_scan()\n",{"type":14,"tag":164,"props":2530,"children":2532},{"class":166,"line":2531},31,[2533],{"type":14,"tag":164,"props":2534,"children":2535},{},[2536],{"type":20,"value":2537},"    rr.log(\"robot\u002Flidar\", rr.Points3D(positions=lidar_points, radii=0.02))\n",{"type":14,"tag":164,"props":2539,"children":2541},{"class":166,"line":2540},32,[2542],{"type":14,"tag":164,"props":2543,"children":2544},{"emptyLinePlaceholder":317},[2545],{"type":20,"value":320},{"type":14,"tag":164,"props":2547,"children":2549},{"class":166,"line":2548},33,[2550],{"type":14,"tag":164,"props":2551,"children":2552},{},[2553],{"type":20,"value":2554},"    # Sensor readings\n",{"type":14,"tag":164,"props":2556,"children":2558},{"class":166,"line":2557},34,[2559],{"type":14,"tag":164,"props":2560,"children":2561},{},[2562],{"type":20,"value":2563},"    rr.log(\"robot\u002Fbattery\", rr.Scalars(get_battery_level()))\n",{"type":14,"tag":164,"props":2565,"children":2567},{"class":166,"line":2566},35,[2568],{"type":14,"tag":164,"props":2569,"children":2570},{},[2571],{"type":20,"value":2572},"    rr.log(\"robot\u002Fspeed\", rr.Scalars(get_speed()))\n",{"type":14,"tag":164,"props":2574,"children":2576},{"class":166,"line":2575},36,[2577],{"type":14,"tag":164,"props":2578,"children":2579},{},[2580],{"type":20,"value":2581},"    rr.log(\"robot\u002Fmotor_temp\", rr.Scalars(get_motor_temperature()))\n",{"type":14,"tag":164,"props":2583,"children":2585},{"class":166,"line":2584},37,[2586],{"type":14,"tag":164,"props":2587,"children":2588},{"emptyLinePlaceholder":317},[2589],{"type":20,"value":320},{"type":14,"tag":164,"props":2591,"children":2593},{"class":166,"line":2592},38,[2594],{"type":14,"tag":164,"props":2595,"children":2596},{},[2597],{"type":20,"value":2598},"    # Status log\n",{"type":14,"tag":164,"props":2600,"children":2602},{"class":166,"line":2601},39,[2603],{"type":14,"tag":164,"props":2604,"children":2605},{},[2606],{"type":20,"value":2607},"    rr.log(\"robot\u002Flogs\", rr.TextLog(f\"Frame {frame}: position ({x:.2f}, {y:.2f})\"))\n",{"type":14,"tag":164,"props":2609,"children":2611},{"class":166,"line":2610},40,[2612],{"type":14,"tag":164,"props":2613,"children":2614},{"emptyLinePlaceholder":317},[2615],{"type":20,"value":320},{"type":14,"tag":164,"props":2617,"children":2619},{"class":166,"line":2618},41,[2620],{"type":14,"tag":164,"props":2621,"children":2622},{},[2623],{"type":20,"value":2624},"    frame += 1\n",{"type":14,"tag":164,"props":2626,"children":2628},{"class":166,"line":2627},42,[2629],{"type":14,"tag":164,"props":2630,"children":2631},{},[2632],{"type":20,"value":2633},"    time.sleep(0.05)  # 20 fps\n",{"type":14,"tag":46,"props":2635,"children":2636},{},[],{"type":14,"tag":50,"props":2638,"children":2640},{"id":2639},"complete-example-ml-training",[2641],{"type":20,"value":2642},"Complete Example: ML Training",{"type":14,"tag":22,"props":2644,"children":2645},{},[2646],{"type":20,"value":2647},"Log your training run and watch metrics in real time:",{"type":14,"tag":62,"props":2649,"children":2651},{"code":2650,"language":145,"meta":7,"className":202,"style":7},"import rerun as rr\n\nrr.init(\"training_run_001\")\nrr.spawn()\n\nmodel = build_model()\noptimizer = build_optimizer()\n\nfor epoch in range(200):\n    train_loss, train_acc = train_one_epoch(model, optimizer)\n    val_loss, val_acc = validate(model)\n\n    rr.set_time(\"epoch\", sequence=epoch)\n\n    # Training metrics\n    rr.log(\"metrics\u002Ftrain\u002Floss\", rr.Scalars(train_loss))\n    rr.log(\"metrics\u002Ftrain\u002Faccuracy\", rr.Scalars(train_acc))\n\n    # Validation metrics\n    rr.log(\"metrics\u002Fval\u002Floss\", rr.Scalars(val_loss))\n    rr.log(\"metrics\u002Fval\u002Faccuracy\", rr.Scalars(val_acc))\n\n    # Log a sample prediction every 10 epochs\n    if epoch % 10 == 0:\n        sample_input, sample_pred = get_sample_prediction(model)\n        rr.log(\"predictions\u002Finput\", rr.Image(sample_input))\n        rr.log(\"predictions\u002Foutput\", rr.Image(sample_pred))\n        rr.log(\"training\u002Fevents\", rr.TextLog(f\"Epoch {epoch}: val_loss={val_loss:.4f}\"))\n",[2652],{"type":14,"tag":67,"props":2653,"children":2654},{"__ignoreMap":7},[2655,2662,2669,2677,2684,2691,2699,2707,2714,2722,2730,2738,2745,2753,2760,2768,2776,2784,2791,2799,2807,2815,2822,2830,2838,2846,2854,2862],{"type":14,"tag":164,"props":2656,"children":2657},{"class":166,"line":167},[2658],{"type":14,"tag":164,"props":2659,"children":2660},{},[2661],{"type":20,"value":201},{"type":14,"tag":164,"props":2663,"children":2664},{"class":166,"line":313},[2665],{"type":14,"tag":164,"props":2666,"children":2667},{"emptyLinePlaceholder":317},[2668],{"type":20,"value":320},{"type":14,"tag":164,"props":2670,"children":2671},{"class":166,"line":323},[2672],{"type":14,"tag":164,"props":2673,"children":2674},{},[2675],{"type":20,"value":2676},"rr.init(\"training_run_001\")\n",{"type":14,"tag":164,"props":2678,"children":2679},{"class":166,"line":332},[2680],{"type":14,"tag":164,"props":2681,"children":2682},{},[2683],{"type":20,"value":364},{"type":14,"tag":164,"props":2685,"children":2686},{"class":166,"line":341},[2687],{"type":14,"tag":164,"props":2688,"children":2689},{"emptyLinePlaceholder":317},[2690],{"type":20,"value":320},{"type":14,"tag":164,"props":2692,"children":2693},{"class":166,"line":349},[2694],{"type":14,"tag":164,"props":2695,"children":2696},{},[2697],{"type":20,"value":2698},"model = build_model()\n",{"type":14,"tag":164,"props":2700,"children":2701},{"class":166,"line":358},[2702],{"type":14,"tag":164,"props":2703,"children":2704},{},[2705],{"type":20,"value":2706},"optimizer = build_optimizer()\n",{"type":14,"tag":164,"props":2708,"children":2709},{"class":166,"line":367},[2710],{"type":14,"tag":164,"props":2711,"children":2712},{"emptyLinePlaceholder":317},[2713],{"type":20,"value":320},{"type":14,"tag":164,"props":2715,"children":2716},{"class":166,"line":375},[2717],{"type":14,"tag":164,"props":2718,"children":2719},{},[2720],{"type":20,"value":2721},"for epoch in range(200):\n",{"type":14,"tag":164,"props":2723,"children":2724},{"class":166,"line":384},[2725],{"type":14,"tag":164,"props":2726,"children":2727},{},[2728],{"type":20,"value":2729},"    train_loss, train_acc = train_one_epoch(model, optimizer)\n",{"type":14,"tag":164,"props":2731,"children":2732},{"class":166,"line":485},[2733],{"type":14,"tag":164,"props":2734,"children":2735},{},[2736],{"type":20,"value":2737},"    val_loss, val_acc = validate(model)\n",{"type":14,"tag":164,"props":2739,"children":2740},{"class":166,"line":494},[2741],{"type":14,"tag":164,"props":2742,"children":2743},{"emptyLinePlaceholder":317},[2744],{"type":20,"value":320},{"type":14,"tag":164,"props":2746,"children":2747},{"class":166,"line":503},[2748],{"type":14,"tag":164,"props":2749,"children":2750},{},[2751],{"type":20,"value":2752},"    rr.set_time(\"epoch\", sequence=epoch)\n",{"type":14,"tag":164,"props":2754,"children":2755},{"class":166,"line":512},[2756],{"type":14,"tag":164,"props":2757,"children":2758},{"emptyLinePlaceholder":317},[2759],{"type":20,"value":320},{"type":14,"tag":164,"props":2761,"children":2762},{"class":166,"line":1850},[2763],{"type":14,"tag":164,"props":2764,"children":2765},{},[2766],{"type":20,"value":2767},"    # Training metrics\n",{"type":14,"tag":164,"props":2769,"children":2770},{"class":166,"line":2399},[2771],{"type":14,"tag":164,"props":2772,"children":2773},{},[2774],{"type":20,"value":2775},"    rr.log(\"metrics\u002Ftrain\u002Floss\", rr.Scalars(train_loss))\n",{"type":14,"tag":164,"props":2777,"children":2778},{"class":166,"line":2407},[2779],{"type":14,"tag":164,"props":2780,"children":2781},{},[2782],{"type":20,"value":2783},"    rr.log(\"metrics\u002Ftrain\u002Faccuracy\", rr.Scalars(train_acc))\n",{"type":14,"tag":164,"props":2785,"children":2786},{"class":166,"line":2416},[2787],{"type":14,"tag":164,"props":2788,"children":2789},{"emptyLinePlaceholder":317},[2790],{"type":20,"value":320},{"type":14,"tag":164,"props":2792,"children":2793},{"class":166,"line":2425},[2794],{"type":14,"tag":164,"props":2795,"children":2796},{},[2797],{"type":20,"value":2798},"    # Validation metrics\n",{"type":14,"tag":164,"props":2800,"children":2801},{"class":166,"line":2434},[2802],{"type":14,"tag":164,"props":2803,"children":2804},{},[2805],{"type":20,"value":2806},"    rr.log(\"metrics\u002Fval\u002Floss\", rr.Scalars(val_loss))\n",{"type":14,"tag":164,"props":2808,"children":2809},{"class":166,"line":2443},[2810],{"type":14,"tag":164,"props":2811,"children":2812},{},[2813],{"type":20,"value":2814},"    rr.log(\"metrics\u002Fval\u002Faccuracy\", rr.Scalars(val_acc))\n",{"type":14,"tag":164,"props":2816,"children":2817},{"class":166,"line":2452},[2818],{"type":14,"tag":164,"props":2819,"children":2820},{"emptyLinePlaceholder":317},[2821],{"type":20,"value":320},{"type":14,"tag":164,"props":2823,"children":2824},{"class":166,"line":2461},[2825],{"type":14,"tag":164,"props":2826,"children":2827},{},[2828],{"type":20,"value":2829},"    # Log a sample prediction every 10 epochs\n",{"type":14,"tag":164,"props":2831,"children":2832},{"class":166,"line":2470},[2833],{"type":14,"tag":164,"props":2834,"children":2835},{},[2836],{"type":20,"value":2837},"    if epoch % 10 == 0:\n",{"type":14,"tag":164,"props":2839,"children":2840},{"class":166,"line":2479},[2841],{"type":14,"tag":164,"props":2842,"children":2843},{},[2844],{"type":20,"value":2845},"        sample_input, sample_pred = get_sample_prediction(model)\n",{"type":14,"tag":164,"props":2847,"children":2848},{"class":166,"line":2487},[2849],{"type":14,"tag":164,"props":2850,"children":2851},{},[2852],{"type":20,"value":2853},"        rr.log(\"predictions\u002Finput\", rr.Image(sample_input))\n",{"type":14,"tag":164,"props":2855,"children":2856},{"class":166,"line":2496},[2857],{"type":14,"tag":164,"props":2858,"children":2859},{},[2860],{"type":20,"value":2861},"        rr.log(\"predictions\u002Foutput\", rr.Image(sample_pred))\n",{"type":14,"tag":164,"props":2863,"children":2864},{"class":166,"line":2505},[2865],{"type":14,"tag":164,"props":2866,"children":2867},{},[2868],{"type":20,"value":2869},"        rr.log(\"training\u002Fevents\", rr.TextLog(f\"Epoch {epoch}: val_loss={val_loss:.4f}\"))\n",{"type":14,"tag":46,"props":2871,"children":2872},{},[],{"type":14,"tag":50,"props":2874,"children":2876},{"id":2875},"saving-and-replaying-recordings",[2877],{"type":20,"value":2878},"Saving and Replaying Recordings",{"type":14,"tag":22,"props":2880,"children":2881},{},[2882,2884,2889],{"type":20,"value":2883},"Instead of streaming to a live viewer, you can save everything to a ",{"type":14,"tag":67,"props":2885,"children":2887},{"className":2886},[],[2888],{"type":20,"value":2255},{"type":20,"value":2890}," file and replay it later:",{"type":14,"tag":62,"props":2892,"children":2894},{"code":2893,"language":145,"meta":7,"className":202,"style":7},"rr.init(\"my_recording\")\nrr.save(\"robot_run_2026_05_11.rrd\")  # all logs go to this file\n\n# ... your logging code ...\n",[2895],{"type":14,"tag":67,"props":2896,"children":2897},{"__ignoreMap":7},[2898,2906,2914,2921],{"type":14,"tag":164,"props":2899,"children":2900},{"class":166,"line":167},[2901],{"type":14,"tag":164,"props":2902,"children":2903},{},[2904],{"type":20,"value":2905},"rr.init(\"my_recording\")\n",{"type":14,"tag":164,"props":2907,"children":2908},{"class":166,"line":313},[2909],{"type":14,"tag":164,"props":2910,"children":2911},{},[2912],{"type":20,"value":2913},"rr.save(\"robot_run_2026_05_11.rrd\")  # all logs go to this file\n",{"type":14,"tag":164,"props":2915,"children":2916},{"class":166,"line":323},[2917],{"type":14,"tag":164,"props":2918,"children":2919},{"emptyLinePlaceholder":317},[2920],{"type":20,"value":320},{"type":14,"tag":164,"props":2922,"children":2923},{"class":166,"line":332},[2924],{"type":14,"tag":164,"props":2925,"children":2926},{},[2927],{"type":20,"value":2928},"# ... your logging code ...\n",{"type":14,"tag":22,"props":2930,"children":2931},{},[2932],{"type":20,"value":2933},"To replay it:",{"type":14,"tag":62,"props":2935,"children":2937},{"code":2936,"language":157,"meta":7,"className":158,"style":7},"rerun robot_run_2026_05_11.rrd\n",[2938],{"type":14,"tag":67,"props":2939,"children":2940},{"__ignoreMap":7},[2941],{"type":14,"tag":164,"props":2942,"children":2943},{"class":166,"line":167},[2944,2948],{"type":14,"tag":164,"props":2945,"children":2946},{"style":171},[2947],{"type":20,"value":196},{"type":14,"tag":164,"props":2949,"children":2950},{"style":177},[2951],{"type":20,"value":2952}," robot_run_2026_05_11.rrd\n",{"type":14,"tag":22,"props":2954,"children":2955},{},[2956],{"type":20,"value":2957},"Or load it in the React viewer:",{"type":14,"tag":62,"props":2959,"children":2961},{"code":2960,"language":2003,"meta":7,"className":2004,"style":7},"\u003CWebViewer rrd=\"\u002Frecordings\u002Frobot_run_2026_05_11.rrd\" width=\"100%\" height=\"600px\" \u002F>\n",[2962],{"type":14,"tag":67,"props":2963,"children":2964},{"__ignoreMap":7},[2965],{"type":14,"tag":164,"props":2966,"children":2967},{"class":166,"line":167},[2968,2973,2978,2983,2987,2992,2997,3001,3005,3010,3014,3018],{"type":14,"tag":164,"props":2969,"children":2970},{"style":2020},[2971],{"type":20,"value":2972},"\u003C",{"type":14,"tag":164,"props":2974,"children":2975},{"style":2141},[2976],{"type":20,"value":2977},"WebViewer",{"type":14,"tag":164,"props":2979,"children":2980},{"style":171},[2981],{"type":20,"value":2982}," rrd",{"type":14,"tag":164,"props":2984,"children":2985},{"style":2014},[2986],{"type":20,"value":2105},{"type":14,"tag":164,"props":2988,"children":2989},{"style":177},[2990],{"type":20,"value":2991},"\"\u002Frecordings\u002Frobot_run_2026_05_11.rrd\"",{"type":14,"tag":164,"props":2993,"children":2994},{"style":171},[2995],{"type":20,"value":2996}," width",{"type":14,"tag":164,"props":2998,"children":2999},{"style":2014},[3000],{"type":20,"value":2105},{"type":14,"tag":164,"props":3002,"children":3003},{"style":177},[3004],{"type":20,"value":2115},{"type":14,"tag":164,"props":3006,"children":3007},{"style":171},[3008],{"type":20,"value":3009}," height",{"type":14,"tag":164,"props":3011,"children":3012},{"style":2014},[3013],{"type":20,"value":2105},{"type":14,"tag":164,"props":3015,"children":3016},{"style":177},[3017],{"type":20,"value":2125},{"type":14,"tag":164,"props":3019,"children":3020},{"style":2020},[3021],{"type":20,"value":3022}," \u002F>\n",{"type":14,"tag":46,"props":3024,"children":3025},{},[],{"type":14,"tag":50,"props":3027,"children":3029},{"id":3028},"using-in-jupyter-notebooks",[3030],{"type":20,"value":3031},"Using in Jupyter Notebooks",{"type":14,"tag":22,"props":3033,"children":3034},{},[3035],{"type":20,"value":3036},"The viewer embeds directly in Jupyter notebooks — no separate window needed:",{"type":14,"tag":62,"props":3038,"children":3040},{"code":3039,"language":145,"meta":7,"className":202,"style":7},"import rerun as rr\n\nrr.init(\"notebook_demo\")\nrr.notebook_show(width=900, height=500)\n\n# Everything you log appears inline in the notebook\nrr.log(\"points\", rr.Points3D([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))\nrr.log(\"metrics\u002Fvalue\", rr.Scalars(42.0))\n",[3041],{"type":14,"tag":67,"props":3042,"children":3043},{"__ignoreMap":7},[3044,3051,3058,3066,3074,3081,3089,3097],{"type":14,"tag":164,"props":3045,"children":3046},{"class":166,"line":167},[3047],{"type":14,"tag":164,"props":3048,"children":3049},{},[3050],{"type":20,"value":201},{"type":14,"tag":164,"props":3052,"children":3053},{"class":166,"line":313},[3054],{"type":14,"tag":164,"props":3055,"children":3056},{"emptyLinePlaceholder":317},[3057],{"type":20,"value":320},{"type":14,"tag":164,"props":3059,"children":3060},{"class":166,"line":323},[3061],{"type":14,"tag":164,"props":3062,"children":3063},{},[3064],{"type":20,"value":3065},"rr.init(\"notebook_demo\")\n",{"type":14,"tag":164,"props":3067,"children":3068},{"class":166,"line":332},[3069],{"type":14,"tag":164,"props":3070,"children":3071},{},[3072],{"type":20,"value":3073},"rr.notebook_show(width=900, height=500)\n",{"type":14,"tag":164,"props":3075,"children":3076},{"class":166,"line":341},[3077],{"type":14,"tag":164,"props":3078,"children":3079},{"emptyLinePlaceholder":317},[3080],{"type":20,"value":320},{"type":14,"tag":164,"props":3082,"children":3083},{"class":166,"line":349},[3084],{"type":14,"tag":164,"props":3085,"children":3086},{},[3087],{"type":20,"value":3088},"# Everything you log appears inline in the notebook\n",{"type":14,"tag":164,"props":3090,"children":3091},{"class":166,"line":358},[3092],{"type":14,"tag":164,"props":3093,"children":3094},{},[3095],{"type":20,"value":3096},"rr.log(\"points\", rr.Points3D([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))\n",{"type":14,"tag":164,"props":3098,"children":3099},{"class":166,"line":367},[3100],{"type":14,"tag":164,"props":3101,"children":3102},{},[3103],{"type":20,"value":3104},"rr.log(\"metrics\u002Fvalue\", rr.Scalars(42.0))\n",{"type":14,"tag":46,"props":3106,"children":3107},{},[],{"type":14,"tag":50,"props":3109,"children":3111},{"id":3110},"output-options-summary",[3112],{"type":20,"value":3113},"Output Options Summary",{"type":14,"tag":3115,"props":3116,"children":3117},"table",{},[3118,3137],{"type":14,"tag":3119,"props":3120,"children":3121},"thead",{},[3122],{"type":14,"tag":3123,"props":3124,"children":3125},"tr",{},[3126,3132],{"type":14,"tag":3127,"props":3128,"children":3129},"th",{},[3130],{"type":20,"value":3131},"What you want",{"type":14,"tag":3127,"props":3133,"children":3134},{},[3135],{"type":20,"value":3136},"How",{"type":14,"tag":3138,"props":3139,"children":3140},"tbody",{},[3141,3159,3175,3192,3209,3226],{"type":14,"tag":3123,"props":3142,"children":3143},{},[3144,3150],{"type":14,"tag":3145,"props":3146,"children":3147},"td",{},[3148],{"type":20,"value":3149},"Open viewer on your machine",{"type":14,"tag":3145,"props":3151,"children":3152},{},[3153],{"type":14,"tag":67,"props":3154,"children":3156},{"className":3155},[],[3157],{"type":20,"value":3158},"rr.spawn()",{"type":14,"tag":3123,"props":3160,"children":3161},{},[3162,3167],{"type":14,"tag":3145,"props":3163,"children":3164},{},[3165],{"type":20,"value":3166},"Save to file for later",{"type":14,"tag":3145,"props":3168,"children":3169},{},[3170],{"type":14,"tag":67,"props":3171,"children":3173},{"className":3172},[],[3174],{"type":20,"value":2263},{"type":14,"tag":3123,"props":3176,"children":3177},{},[3178,3183],{"type":14,"tag":3145,"props":3179,"children":3180},{},[3181],{"type":20,"value":3182},"Stream to a remote viewer",{"type":14,"tag":3145,"props":3184,"children":3185},{},[3186],{"type":14,"tag":67,"props":3187,"children":3189},{"className":3188},[],[3190],{"type":20,"value":3191},"rr.connect_grpc(\"ip:port\")",{"type":14,"tag":3123,"props":3193,"children":3194},{},[3195,3200],{"type":14,"tag":3145,"props":3196,"children":3197},{},[3198],{"type":20,"value":3199},"Embed in a web app",{"type":14,"tag":3145,"props":3201,"children":3202},{},[3203],{"type":14,"tag":67,"props":3204,"children":3206},{"className":3205},[],[3207],{"type":20,"value":3208},"@credvault\u002Frerun-viewer-react",{"type":14,"tag":3123,"props":3210,"children":3211},{},[3212,3217],{"type":14,"tag":3145,"props":3213,"children":3214},{},[3215],{"type":20,"value":3216},"Use in a Jupyter notebook",{"type":14,"tag":3145,"props":3218,"children":3219},{},[3220],{"type":14,"tag":67,"props":3221,"children":3223},{"className":3222},[],[3224],{"type":20,"value":3225},"rr.notebook_show()",{"type":14,"tag":3123,"props":3227,"children":3228},{},[3229,3234],{"type":14,"tag":3145,"props":3230,"children":3231},{},[3232],{"type":20,"value":3233},"Get raw bytes (for custom transport)",{"type":14,"tag":3145,"props":3235,"children":3236},{},[3237],{"type":14,"tag":67,"props":3238,"children":3240},{"className":3239},[],[3241],{"type":20,"value":3242},"rr.memory_recording()",{"type":14,"tag":46,"props":3244,"children":3245},{},[],{"type":14,"tag":50,"props":3247,"children":3249},{"id":3248},"support",[3250],{"type":20,"value":3251},"Support",{"type":14,"tag":22,"props":3253,"children":3254},{},[3255,3257,3262],{"type":20,"value":3256},"Questions or issues with the visualization platform? File a support ticket from your dashboard or email ",{"type":14,"tag":82,"props":3258,"children":3259},{},[3260],{"type":20,"value":3261},"credvault.net\u002Fsupport",{"type":20,"value":3263},".",{"type":14,"tag":3265,"props":3266,"children":3267},"style",{},[3268],{"type":20,"value":3269},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":313,"depth":313,"links":3271},[3272,3273,3278,3279,3280,3281,3288,3294,3295,3299,3300,3301,3302,3303,3304,3305,3306,3307],{"id":52,"depth":313,"text":55},{"id":138,"depth":313,"text":141,"children":3274},[3275,3276,3277],{"id":145,"depth":323,"text":148},{"id":216,"depth":323,"text":219},{"id":251,"depth":323,"text":254},{"id":288,"depth":313,"text":291},{"id":529,"depth":313,"text":532},{"id":615,"depth":313,"text":618},{"id":769,"depth":313,"text":772,"children":3282},[3283,3284,3285,3286,3287],{"id":775,"depth":323,"text":778},{"id":878,"depth":323,"text":881},{"id":943,"depth":323,"text":946},{"id":1075,"depth":323,"text":1078},{"id":1132,"depth":323,"text":1135},{"id":1192,"depth":313,"text":1195,"children":3289},[3290,3291,3292,3293],{"id":1198,"depth":323,"text":1201},{"id":1249,"depth":323,"text":1252},{"id":1291,"depth":323,"text":1294},{"id":1388,"depth":323,"text":1391},{"id":1496,"depth":313,"text":1499},{"id":1609,"depth":313,"text":1612,"children":3296},[3297,3298],{"id":1615,"depth":323,"text":1618},{"id":1670,"depth":323,"text":1673},{"id":1722,"depth":313,"text":1725},{"id":1861,"depth":313,"text":1864},{"id":1991,"depth":313,"text":1994},{"id":2271,"depth":313,"text":2274},{"id":2639,"depth":313,"text":2642},{"id":2875,"depth":313,"text":2878},{"id":3028,"depth":313,"text":3031},{"id":3110,"depth":313,"text":3113},{"id":3248,"depth":313,"text":3251},"markdown","content:docs:features:visualization-platform.md","content","docs\u002Ffeatures\u002Fvisualization-platform.md","docs\u002Ffeatures\u002Fvisualization-platform","md",1782233754787]