Import recorded driving sensor data (GPS, camera, lidar, actor tracks, lanes) into scenariobuilder.* objects (GPSData, CameraData, LidarData, ActorTrackData, Trajectory, laneData) and run preprocessing — synchronize, offset correction, crop, normalizeTimestamps, convertTimestamps. Also: compute actor tracks from lidar when no annotations exist, attach camera/lidar mounting + intrinsics, export to MAT/workspace/timetable/script. Use for raw driving dataset files (KITTI, nuScenes, Waymo, Pandaset, ROS/ROS2 bags, .mat, .csv, .mp4) or driving/vehicle/sensor logs that need wrapping. drivingLogAnalyzer (DLA) is OPT-IN ONLY — invoke only on explicit user request ('DLA', 'open in DLA', 'inspect/explore/analyze the recording') or reported sensor problem (sync drift, timestamp mismatch, overlay misalignment). NEVER auto-launch DLA after wrapping (Rule 0). For 'build scenario / export to RoadRunner / drivingScenario / OpenSCENARIO / Unreal / simulate', hand off to matlab-scenario-builder.
npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-driving-data-importer
This skill loads raw driving sensor data into scenariobuilder.* objects (GPSData, CameraData, LidarData, ActorTrackData, Trajectory, laneData) and provides the CLI for every preprocessing step DLA exposes (sync, crop, offset, normalize, convert timestamps). It also covers the drivingLogAnalyzer (DLA) app as an opt-in inspection tool — see *Rule 0* below; DLA is never a default step.
After wrapping is done, the canonical next move is matlab-scenario-builder (trajectory smoothing, scene/scenario generation, lane localization, RoadRunner / drivingScenario / OpenSCENARIO / OpenDRIVE / OpenCRG / Unreal export).
Never call drivingLogAnalyzer unless the user explicitly asks for it or has reported a sensor-data problem DLA is built to debug. Auto-launching DLA after wrapping data is a first-attempt-success failure: it stalls the user (a UI app forces context-switch, scrub, click, confirm) and signals that the agent is not confident the import worked.
When DLA IS allowed — only these two cases:
DLA, drivingLogAnalyzer, "open in DLA", "inspect / visualize / explore / replay / analyze the recording", "open the driving log analyzer".When DLA is NOT allowed (defaults — go straight to matlab-scenario-builder):
If you ever feel an urge to add a "let me open DLA so you can verify" step after wrapping — stop. Save the wrapped objects to sandbox/<dataset>_wrapped.mat, print a short summary, and hand off.
scenariobuilder.* objectsGPSData, CameraData, LidarData, ActorTrackData, Trajectory, or laneDatamatlab-scenario-builder directly. (Rule 0.)matlab-scenario-builder.matlab-scenario-buildermultiSensorTargetTracker, JPDA + smoother) to get cleaner tracks — matlab-scenario-builder Workflow 14matlab-debuggingmatlab-list-products / matlab-install-productsBoundary heuristic: wrapping into scenariobuilder.* and any sync/crop/offset/normalize CLI work belongs here. The moment the user says *scenario / scene / RoadRunner / simulate / drive in a virtual world / export to OpenSCENARIO / virtualize* — wrap, save, hand off. DLA stays parked unless invoked by name or summoned by a reported problem.
Always inspect the dataset structure first. Before writing any import code:
Never run a lidar tracker if the dataset already provides actor tracks or 3D bounding box annotations. Always check first:
object_detection.json, labels/, annotations/, tracking/)ActorTrackDataDriving datasets commonly have two types of recordings:
| Type | Duration | Annotations | Use Case |
|------|----------|-------------|----------|
| Drives/Logs | Long (1-10 min) | Often none | Ego trajectory + road network |
| Sequences/Clips | Short (10-30s) | Usually yes (keyframe or full) | Actor tracks + ego |
Always clarify which type the user's data is before proceeding. If data lacks annotations, inform the user that actor tracks must be computed (via lidar detection/tracking or camera detection) and set expectations about quality.
Before using any transform, verify:
After initial inspection, always present a summary:
Dataset: <name>
Recording: <ID/name>
Duration: <X seconds>
Available sensors:
- GPS: <format, sample count, rate>
- Lidar: <format, frame count, rate, sensor model>
- Camera: <format, frame count, rate, resolution>
- Annotations: <YES/NO — type if yes>
Calibration: <available transforms>
| Format | How to Read |
|--------|-------------|
| JSON (lat/lon/alt arrays) | jsondecode(fileread(file)) |
| HDF5 (fields in groups) | h5read(file, '/group/field') |
| CSV | readtable(file) |
| ROS bag | scenariobuilder.GPSData("file.bag", "/topic") |
| NMEA | Custom parser needed |
Key fields needed: timestamps, latitude, longitude, altitude
| Format | How to Read |
|--------|-------------|
| PCD | pcread(file) |
| PLY | pcread(file) |
| BIN (KITTI format) | reshape(fread(fid,'single'),[4,Inf])' — columns: x,y,z,intensity |
| NPY (custom struct) | Custom reader needed — parse header, read structured bytes |
| LAS/LAZ | lasFileReader(file) then readPointCloud |
Important: Always check the point cloud coordinate frame. Common conventions:
| Format | How to Read |
|--------|-------------|
| Directory of images | imageDatastore(dir) |
| Video file | VideoReader(file) |
| ROS bag | rosbag then read image messages |
Key info needed: timestamps, file paths, intrinsics, distortion model, extrinsics (camera-to-ego)
Calibration files typically provide:
Common pitfall: The naming of extrinsic transforms is inconsistent across datasets. A field named lidar_extrinsics could mean:
Always verify by checking translation values against physical sensor mounting positions (e.g., lidar mounted ~1.7m high should have Z translation ~1.7 in lidar-to-ego).
Common formats:
Per object:
- class: "Car", "Truck", "Pedestrian", etc.
- location_3d: [x, y, z] — center position in some reference frame
- size: [length, width, height] in meters
- orientation: quaternion or yaw angle
- track_id: persistent ID across frames (if temporal tracking exists)
Frame of reference: Annotations may be in:
Always check which frame and transform to ego if needed.
Canonical GPSData construction is THREE lines, always together — bare scenariobuilder.GPSData(...) is incomplete. The post-construction convertTimestamps + normalizeTimestamps calls are part of the canonical construction, not optional cleanup. Downstream APIs (synchronize, trajectory, actorprops, localizeEgoUsingLanes, RoadRunner export) expect numeric timestamps starting at t=0.
% Load timestamps, lat, lon, alt from dataset
gpsData = scenariobuilder.GPSData(timestamps, latitude, longitude, altitude);
% Canonical post-construction pair (always run both)
convertTimestamps(gpsData, "numeric");
timeRef = normalizeTimestamps(gpsData);
If you skip these two lines, the object will silently fail later (sample-rate mismatches in synchronize, scenario time bounds wrong, RoadRunner export errors). Run them every time, even when you "just" construct a GPSData for inspection — and even when the prompt only says "construct the GPSData object."
Altitude handling:
altitude = zeros(...)) — OSM has no elevationWhen per-frame 3D annotations with track IDs exist:
% For each timestamp, collect track IDs and positions
timestamps = <Nx1 numeric>;
trackIDs = cell(N, 1); % each cell: Mx1 string array
positions = cell(N, 1); % each cell: Mx3 [x y z] in ego frame
for i = 1:N
% Get annotations for frame i
frameAnnots = <filter annotations for this frame>;
trackIDs{i} = string({frameAnnots.track_id}');
positions{i} = [frameAnnots.x, frameAnnots.y, frameAnnots.z];
end
trackData = scenariobuilder.ActorTrackData(timestamps, trackIDs, positions);
If annotations are in world frame (not ego frame):
% Transform world positions to ego-relative positions
% ActorTrackData expects positions relative to ego at each timestamp
for i = 1:N
worldPos = positions_world{i};
egoPos = egoPositionAtTime(i); % from GPS/odometry
egoYaw = egoYawAtTime(i);
R = [cos(egoYaw) sin(egoYaw) 0; -sin(egoYaw) cos(egoYaw) 0; 0 0 1];
positions{i} = (worldPos - egoPos) * R';
end
% Match camera image files to timestamps
imageFiles = dir(fullfile(camDir, '*.jpg'));
camTimestamps = <parse timestamps from filenames or metadata>;
cameraData = scenariobuilder.CameraData(camTimestamps, ...
fullfile(camDir, {imageFiles.name}'), Name="FrontCamera");
Always wrap lidar via scenariobuilder.LidarData — this is the only wrapper DLA accepts and the only one downstream Scenario Builder APIs (Workflow 10 OpenCRG extraction, Workflow 11 georeferencing) consume. Do not hand DLA raw pointCloud arrays or paths.
% Match lidar files (.pcd, .ply, .las/.laz) to timestamps
lidarFiles = dir(fullfile(lidarDir, '*.pcd'));
lidarTimestamps = <parse timestamps from filenames or metadata>;
lidarData = scenariobuilder.LidarData(lidarTimestamps, ...
fullfile(lidarDir, {lidarFiles.name}'), Name="OSLidar");
For multi-lidar setups, build one scenariobuilder.LidarData per sensor with a distinct Name (e.g., "OSLidar", "VLP32", "OuterLeft"). DLA will render each in its own pane.
convertTimestamps(gpsData, "numeric");
convertTimestamps(trackData, "numeric");
timeRef = normalizeTimestamps(gpsData);
normalizeTimestamps(trackData, timeRef);
synchronize(trackData, gpsData);
drivingLogAnalyzer does NOT accept programmatic sensor inputs. It opens the app; the user then imports sensors via the GUI (Import → From Workspace). Make sure the wrapped objects are in the base workspace, then launch the app bare:
% Wrapped objects must already exist in the base workspace
% (gpsData, cameraData, lidarData, trackData)
drivingLogAnalyzer; % user clicks Import → From Workspace
Do NOT call forms like drivingLogAnalyzer(sensors, Plot=true) or drivingLogAnalyzer(gpsData, Plot=true) — those signatures are not supported and will error. Remember Rule 0: launch DLA only when the user explicitly asks for it or reports a sensor-data problem DLA is built to debug. (See workflow-driving-log-analyzer.md for the full opt-in recipe.)
If the dataset has NO pre-computed 3D bounding boxes or temporal tracks, actor tracks must be computed. Always inform the user about:
% Requires a trained model (e.g., PointPillars)
detector = pointPillarsObjectDetector(net, pcRange, classNames, anchorBoxes);
bboxes = detect(detector, ptCloud);
% Per frame:
% 1. Transform lidar to ego frame
% 2. Remove ground plane
% 3. Filter ROI
% 4. Euclidean clustering
% 5. Size filtering
% 6. Feed detections to tracker (JPDA or GNN)
Known limitations of clustering approach:
% Use pretrained camera detector
detector = vehicleDetectorYOLOv2(); % or vehicleDetectorFasterRCNN()
[bboxes, scores] = detect(detector, img);
Limitation: Gives 2D boxes only. Requires depth estimation or lidar fusion for 3D positions.
To verify detection alignment or overlay lidar on camera:
% Transform lidar to camera frame
T_lidar2cam = inv(T_cam2ego) * T_lidar2ego; % compose transforms
pts_cam = (T_lidar2cam * [pts_lidar, ones(N,1)]')';
% Project to pixels (pinhole model)
inFront = pts_cam(:,3) > 0;
u = fx * pts_cam(inFront,1) ./ pts_cam(inFront,3) + cx;
v = fy * pts_cam(inFront,2) ./ pts_cam(inFront,3) + cy;
% Display
imshow(img); hold on;
scatter(u, v, 1, depth, 'filled');
For fisheye cameras: Standard pinhole projection will have errors at image edges. Use the camera's distortion model for accurate projection.
----
Copyright 2026 The MathWorks, Inc.
----
Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas
Use this skill any time a spreadsheet file is the primary input or output. This means any task where the user wants to: open, read, edit, or fix an existing .xlsx, .xlsm, .csv, or .tsv file (e.g., adding columns, computing formulas, formatting, charting, cleaning messy data); create a new spreadsheet from scratch or from other data sources; or convert between tabular file formats. Trigger especially when the user references a spreadsheet file by name or path — even casually (like \"the xlsx in my downloads\") — and wants something done to it or produced from it. Also trigger for cleaning or restructuring messy tabular data files (malformed rows, misplaced headers, junk data) into proper spreadsheets. The deliverable must be a spreadsheet file. Do NOT trigger when the primary deliverable is a Word document, HTML report, standalone Python script, database pipeline, or Google Sheets API integration, even if tabular data is involved.
Picks random winners from lists, spreadsheets, or Google Sheets for giveaways, raffles, and contests. Ensures fair, unbiased selection with transparency.
Query openFDA API for drugs, devices, adverse events, recalls, regulatory submissions (510k, PMA), substance identification (UNII), for FDA regulatory data analysis and safety research.
MATLAB and GNU Octave numerical computing for matrix operations, data analysis, visualization, and scientific computing. Use when writing MATLAB/Octave scripts for linear algebra, signal processing, image processing, differential equations, optimization, statistics, or creating scientific visualizations. Also use when the user needs help with MATLAB syntax, functions, or wants to convert between MATLAB and Python code. Scripts can be executed with MATLAB or the open-source GNU Octave interpreter.
UMAP dimensionality reduction. Fast nonlinear manifold learning for 2D/3D visualization, clustering preprocessing (HDBSCAN), supervised/parametric UMAP, for high-dimensional data.
Creating interactive data visualisations using d3.js. This skill should be used when creating custom charts, graphs, network diagrams, geographic visualisations, or any complex SVG-based data visualisation that requires fine-grained control over visual elements, transitions, or interactions. Use this for bespoke visualisations beyond standard charting libraries, whether in React, Vue, Svelte, vanilla JavaScript, or any other environment.
Access AlphaFold 200M+ AI-predicted protein structures. Retrieve structures by UniProt ID, download PDB/mmCIF files, analyze confidence metrics (pLDDT, PAE), for drug discovery and structural biology.
Take matlab/matlab-driving-data-importer from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.