[{"content":"","date":"10 August 2026","externalUrl":null,"permalink":"/tags/3d-printing/","section":"Tags","summary":"","title":"3D Printing","type":"tags"},{"content":"","date":"10 August 2026","externalUrl":null,"permalink":"/tags/graph-neural-networks/","section":"Tags","summary":"","title":"Graph Neural Networks","type":"tags"},{"content":"This project tackles print path planning for lattice structures using reinforcement learning. Given a lattice (vertices + edges from LatticeQuery), the goal is to find the order to print every strut without the nozzle colliding with already printed material.\nThe approach is based on the AERO algorithm from Weeks et al., Adv. Mater. 2022, which uses Fleury\u0026rsquo;s algorithm to find Eulerian paths through a lattice graph. This project reimplements the geometric constraint checking from the paper, then replaces the graph traversal algorithm with a learned policy using a Graph Attention Network (actor) and Graph Isomorphism Network (critic).\nPre-computation (shared across all methods) Before any path planning, two geometric checks run once on the lattice:\nEdge directionality. Each strut\u0026rsquo;s angle from vertical is computed. Struts within 30° of vertical must be printed top to bottom only (directed), since the nozzle body would collide with the strut if printing upward. All other struts are bidirectional.\nBlocking check. Every pair of struts is checked: would printing strut A block future nozzle access to strut B? The check projects both struts onto the xy plane and examines parallel overlap, crossing intersections, shared vertex angles, and closest 3D distance. The result is a blocking table: for each strut, a list of struts it would block if printed now.\nAERO (baseline) The paper\u0026rsquo;s algorithm. Fleury\u0026rsquo;s algorithm traverses the lattice graph, preferring non-bridge edges (edges whose removal would disconnect the remaining graph). When no valid edges remain at the current vertex, the nozzle lifts and travels to a new starting vertex. This repeats until all edges are printed.\nOn a 2×2×2 Simple Cubic lattice (27 vertices, 54 edges), AERO completes 54/54 edges in 20 separate paths with 19 travel moves.\nAERO baseline: 54/54 edges printed in 20 paths with 19 travel moves. Method 1 (RL, 4 features) Replaces Fleury\u0026rsquo;s algorithm with a GAT actor + GIN critic. The GAT scores each valid edge and outputs a probability distribution. The agent samples an edge, prints it, and receives a reward. The GIN evaluates the current graph state and predicts future reward, providing the learning signal for the actor via advantage based policy gradient.\nNode features: [x, y, z, is_nozzle_here] (4 features). Travel is a learned action: when no valid edges exist at the current vertex, the GAT scores reachable vertices and picks a travel destination. Travel penalty: -2 per travel, -1 per print, +100 for completion.\nObservation: Method 1 completes 54/54 but the travel count does not improve significantly over training. The network cannot distinguish between a state with 10 edges printed and 40 edges printed because the node features contain no information about print progress. The x, y, z coordinates never change, and the nozzle position alone is insufficient context.\nMethod 1: 54/54 edges printed, but travel count doesn\u0026rsquo;t improve over training. Method 2 (RL, 6 features, normalized) Same architecture as Method 1 with two changes:\nNode features expanded to 6: [x/max_x, y/max_y, z/max_z, is_nozzle_here, printed_ratio, global_progress]. The coordinates are normalized to [0,1] so they don\u0026rsquo;t dominate the binary features. printed_ratio is the fraction of each vertex\u0026rsquo;s adjacent edges that have been printed. global_progress is the fraction of all edges printed so far.\nTravel penalty reduced to -1 (same as a print move). AERO needed 19 travels for 54 edges, so travel is a normal part of the solution, not a failure to penalize heavily.\nObservation: Method 2 learns faster and achieves higher best reward. The printed_ratio feature lets the GAT see which parts of the lattice are \u0026ldquo;used up\u0026rdquo; and which still need work. The global_progress feature lets the GIN distinguish early game states from late game states, enabling different value estimates for the same local configuration at different stages of completion.\nMethod 2: faster learning and higher best reward with progress-aware features. ","date":"10 August 2026","externalUrl":null,"permalink":"/posts/meca500_rl/","section":"Posts","summary":"This project tackles print path planning for lattice structures using reinforcement learning. Given a lattice (vertices + edges from LatticeQuery), the goal is to find the order to print every strut without the nozzle colliding with already printed material.\n","title":"Lattice Print Path Planning with Reinforcement Learning","type":"posts"},{"content":"","date":"10 August 2026","externalUrl":null,"permalink":"/tags/path-planning/","section":"Tags","summary":"","title":"Path Planning","type":"tags"},{"content":"","date":"10 August 2026","externalUrl":null,"permalink":"/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":"","date":"10 August 2026","externalUrl":null,"permalink":"/tags/python/","section":"Tags","summary":"","title":"Python","type":"tags"},{"content":"","date":"10 August 2026","externalUrl":null,"permalink":"/tags/pytorch/","section":"Tags","summary":"","title":"PyTorch","type":"tags"},{"content":"","date":"10 August 2026","externalUrl":null,"permalink":"/tags/reinforcement-learning/","section":"Tags","summary":"","title":"Reinforcement Learning","type":"tags"},{"content":"","date":"10 August 2026","externalUrl":null,"permalink":"/","section":"Rishika Bera","summary":"","title":"Rishika Bera","type":"page"},{"content":"","date":"10 August 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"10 July 2026","externalUrl":null,"permalink":"/tags/c++/","section":"Tags","summary":"","title":"C++","type":"tags"},{"content":"","date":"10 July 2026","externalUrl":null,"permalink":"/tags/g-code/","section":"Tags","summary":"","title":"G-Code","type":"tags"},{"content":"","date":"10 July 2026","externalUrl":null,"permalink":"/tags/meca500-6-dof-arm/","section":"Tags","summary":"","title":"Meca500 6-DOF Arm","type":"tags"},{"content":"","date":"10 July 2026","externalUrl":null,"permalink":"/tags/motion-planning/","section":"Tags","summary":"","title":"Motion Planning","type":"tags"},{"content":"","date":"10 July 2026","externalUrl":null,"permalink":"/tags/moveit-2/","section":"Tags","summary":"","title":"MoveIt 2","type":"tags"},{"content":"","date":"10 July 2026","externalUrl":null,"permalink":"/tags/robot-driver-development/","section":"Tags","summary":"","title":"Robot Driver Development","type":"tags"},{"content":" Overview I built a ROS 2 package that drives a Meca500 6-DOF arm (5 μm resolution) as a 3D printer through MoveIt 2. A custom ros2_control hardware interface bridges the Meca500\u0026rsquo;s proprietary TCP API to MoveIt 2, so real trajectory planning and execution run on the physical arm. A mounted Ender3 extruder handles filament feed and heating over USB serial — the arm does all of the XYZ motion.\nThe print pipeline sweeps the robot\u0026rsquo;s reachable workspace, centers and clips sliced G-code onto the densest reachable region, then executes it through a patched build of MoveIt 2\u0026rsquo;s Pilz Industrial Motion Planner. Consecutive moves of the same type are grouped into batches, and each batch is planned as one blended sequence:\nLIN for straight / extruding moves CIRC for arcs, with Pilz\u0026rsquo;s colinearity tolerance lowered to match the Meca500\u0026rsquo;s 5 μm resolution Before the arm moves, a pre-planning pass runs the whole file plan-only to discover the real feed-rate range, so extrusion can be rescaled to the Ender3\u0026rsquo;s physical limits.\nSystem Architecture ROS 2 Package Breakdown msr_meca500_hardware The ros2_control hardware interface (Meca500System) brides the Meca500\u0026rsquo;s TCP API to MoveIt 2. It streams joint commands and state over control/monitoring ports 10000/10001; use_mock_hardware:=true swaps in mock_components for offline runs.\nmsr_meca500_moveit MoveIt 2 configuration and demo.launch.py spawn move_group, robot_state_publisher, ros2_control, and the arm controller. I set up two planning pipelines: OMPL for free-space moves and a patched Pilz Industrial Motion Planner for LIN / CIRC.\nmsr_meca500_robot The robot description (the meca500 arm, the mounted Ender3 extruder, the nozzle tool frame, and the print-bed environment) is modeled in URDF/Xacro. I made the extruder and background meshes toggleable (use_extruder, use_background) and swappable, so that I can drop in a different end-effector or rig later.\nmsr_meca500_print_pipeline The full print pipeline package contains four nodes plus the launch scripts:\nbed_from_touches : takes joint configurations recorded with the nozzle touching the bed, runs forward kinematics on each, and fits the bed plane by SVD. Publishes the result through /table_service. A flat default pose is used when no touch data is supplied. planningscene : holds the bed pose, publishes /table_marker, and registers the bed as a MoveIt collision object. reachability : sweeps an N×N grid over the bed for collision-free IK with an approach-standoff search, writing reachable_points.csv. gcode_print_executor : first plans the whole preprocessed G-code once without executing, to calibrate feed rates to what the extruder can actually push. It then groups the moves into batches by type and plans each batch as one blended Pilz LIN/CIRC sequence. Execution drives the arm through MoveIt while the Ender3 feeds filament and holds temperature over serial. Any arc Pilz can\u0026rsquo;t plan falls back to a straight line Configuration lives in three YAML files: machine_settings.yaml (your hardware), bed_settings.yaml (touch-probe output), and print_tuning.yaml (author-tuned constants, including a first-layer nozzle_bed_gap trim).\nmsr_gcode Contains a Python preprocessor I wrote that unzips the sliced .3mf, centers the print on the densest reachable region, drops out-of-workspace moves as gaps (no scaling or distortion), and repairs degenerate arc geometry and a C++ parser library the executor calls at run time.\nDemos Below are clips of my setup printing a 5 cm × 5 cm × 5 cm cube on real hardware.\nYour browser cannot play this video. Download video.\nYour browser cannot play this video. Download video.\nYour browser cannot play this video. Download video.\nIn the RViz views below, the green line traces every sampled end-effector position and the purple line traces only where the nozzle was extruding. Both of the next two demos rely on my pipeline\u0026rsquo;s reachability-aware placement to fit the print onto the workspace.\nMy full pipeline plans and executes a sliced boat model (21 layers) in batched Pilz LIN / CIRC sequences on a flat bed:\nYour browser cannot play this video. Download video.\nWith no extruder, I tilt the bed to an arbitrary pose via /table_service, and my pipeline prints a cube (7 layers) onto the reoriented surface:\nYour browser cannot play this video. Download video.\nStraight-line G1 moves sent directly through /goal_service and executed with the Pilz LIN planner:\nYour browser cannot play this video. Download video.\nA smoke test of msr_meca500_hardware, driving basic robot motion through the ros2_control hardware interface:\nYour browser cannot play this video. Download video.\nWhat\u0026rsquo;s Next Next up: adaptive nozzle orientation for steep struts and overhangs.\nCode My full implementation is on GitHub.\n","date":"10 July 2026","externalUrl":null,"permalink":"/posts/meca500_3d_printer/","section":"Posts","summary":" Overview I built a ROS 2 package that drives a Meca500 6-DOF arm (5 μm resolution) as a 3D printer through MoveIt 2. A custom ros2_control hardware interface bridges the Meca500’s proprietary TCP API to MoveIt 2, so real trajectory planning and execution run on the physical arm. A mounted Ender3 extruder handles filament feed and heating over USB serial — the arm does all of the XYZ motion.\n","title":"Robotic 3D Printing with a Meca500","type":"posts"},{"content":"","date":"10 July 2026","externalUrl":null,"permalink":"/tags/ros-2/","section":"Tags","summary":"","title":"ROS 2","type":"tags"},{"content":"","date":"10 June 2026","externalUrl":null,"permalink":"/tags/computer-vision/","section":"Tags","summary":"","title":"Computer Vision","type":"tags"},{"content":"","date":"10 June 2026","externalUrl":null,"permalink":"/tags/knowledge-distillation/","section":"Tags","summary":"","title":"Knowledge Distillation","type":"tags"},{"content":"","date":"10 June 2026","externalUrl":null,"permalink":"/tags/raspberry-pi/","section":"Tags","summary":"","title":"Raspberry Pi","type":"tags"},{"content":"","date":"10 June 2026","externalUrl":null,"permalink":"/tags/yolo/","section":"Tags","summary":"","title":"YOLO","type":"tags"},{"content":" Joint project with Theo Coulson, Northwestern University Distilling a fine-tuned YOLO detector into a custom architecture small enough to run in real time on a Raspberry Pi Zero 2W, so a drone can spot and land on a landing platform on its own — at about a tenth of the teacher\u0026rsquo;s parameter count. Read the full report for the complete writeup.\nThe Platform Built on a swarm-robotics drone platform from Mike Rubenstein\u0026rsquo;s lab at Northwestern, with a Raspberry Pi camera module added to the underside. The model itself wasn\u0026rsquo;t integrated with the flight controller due to a hardware serial issue, so it was evaluated by holding the drone over the landing pad by hand.\nArchitecture A standard YOLO has a backbone, a multi-scale neck (FPN), and a head — the neck exists to handle objects of wildly different sizes. Since we only ever detect one object of roughly fixed size, we drop the neck entirely and predict from a single scale, replacing YOLO11\u0026rsquo;s C3k2 blocks with cheaper depthwise-separable ones:\nDSConv — splits a regular convolution into a per-channel spatial pass and a 1×1 channel-mixing pass, for a fraction of the compute. CSP block — splits the input in half, runs one half through two DSConvs, skips the other, concatenates and mixes — a cheap stand-in for C3k2 with a clean gradient path. Backbone — strided ConvBnAct + CSP blocks downsampling 224 → 14, same principle as YOLO11 with lighter blocks. Spatial pooling to 4×4 instead of 1×1, so the head keeps a coarse sense of where the pad is, not just whether it\u0026rsquo;s present. Head — a 2-layer FC net predicting confidence + box corners. 283,541 parameters vs. YOLO11n\u0026rsquo;s 2,624,080 — about a 9× reduction.\nInput image3 × 224 × 224 ConvBnAct ×2conv + batchnorm + ReLU6, downsample 224 → 56 CSP blockfeature learning at 56 ConvBnActdownsample 56 → 28 CSP blockfeature learning at 28 ConvBnActdownsample 28 → 14 Spatial pooling14 → 4 × 4 grid Flatten Head2-layer fully connected confidence, x1, y1, x2, y2 Figure — custom student model architecture.\nTraining Teacher: YOLO11l, fine-tuned 50 epochs on a Roboflow-labeled dataset. Student loss combines detection loss (BCE on confidence + weighted MSE on box corners) with a feature-distillation loss — matching teacher and student feature maps location-by-location, via a learned adapter, so the teacher\u0026rsquo;s sense of where the pad is transfers along with whether it\u0026rsquo;s there. Distillation took about 45 minutes on an RTX 500 Ada.\nResults On held-out test set images, the student localizes the pad well across a range of scales and distances:\nBenchmarked on a laptop, 50 runs on a test image:\nPerformance comparison on test image (50 runs) MetricYOLO11nCustom Model Params2,624,080283,541 Size (MB)10.011.08 Avg (ms)105.0711.4 Best (ms)104.621.11 Worst (ms)108.211.30 FPS9.52880.45 Roughly 10× less memory and 100× faster inference than the teacher, on the same hardware. On the Pi Zero 2W itself, inference averaged ~180ms — plenty fast for spotting a static landing pad. Testing was done by holding the drone over the platform by hand:\nExamples of inference from the Pi:\nLeft to right: a successful detection, a rejected borderline case, and a correct non-detection.\nOn-device performance was noticeably shakier than on the laptop test set — a mismatch between training data (phone camera, portrait, night) and the Pi\u0026rsquo;s camera (no IR filter, daylight, different aspect ratio) accounts for most of the gap.\n","date":"10 June 2026","externalUrl":null,"permalink":"/posts/yolo_distillation/","section":"Posts","summary":"Joint project with Theo Coulson, Northwestern University Distilling a fine-tuned YOLO detector into a custom architecture small enough to run in real time on a Raspberry Pi Zero 2W, so a drone can spot and land on a landing platform on its own — at about a tenth of the teacher’s parameter count. Read the full report for the complete writeup.\n","title":"YOLO Distillation for Real-Time Inference on a Raspberry Pi Zero","type":"posts"},{"content":"","date":"9 May 2026","externalUrl":null,"permalink":"/tags/conditional-u-net/","section":"Tags","summary":"","title":"Conditional U-Net","type":"tags"},{"content":"","date":"9 May 2026","externalUrl":null,"permalink":"/tags/diffusion-model/","section":"Tags","summary":"","title":"Diffusion Model","type":"tags"},{"content":" Sketch2Real generates photorealistic images from colored sketches using a conditional diffusion model built on a U-Net architecture, trained on the COCO dataset.\nYour browser cannot play this video. Download video.\nSketch Generation Given a COCO image, a paired sketch is generated by converting to grayscale, inverting, applying Gaussian blur, thresholding for edges, then replacing those edges with the original colors.\nHow it Works The model reverses a diffusion process — starting from Gaussian noise and iteratively denoising, conditioned on the sketch. The U-Net takes the noisy image and sketch as a 6-channel input plus a timestep embedding, and predicts the noise to remove.\nModel 1 — Proof of Concept 5K images at 128×128, cosine noise schedule, L1 loss. Training plateaued around epoch 160 — dataset too small to generalize further.\nModel 2 — Full Scale 118K images at 256×256, offset cosine schedule, MSE loss, CosineAnnealingLR. Significantly sharper results.\nCheck out the GitHub repo for full architecture details, training instructions, and dataset setup.\n","date":"9 May 2026","externalUrl":null,"permalink":"/posts/sketch2real/","section":"Posts","summary":" Sketch2Real generates photorealistic images from colored sketches using a conditional diffusion model built on a U-Net architecture, trained on the COCO dataset.\n","title":"Sketch2Real - Colored Sketch to Photorealistic Image Generation","type":"posts"},{"content":"","date":"31 March 2026","externalUrl":null,"permalink":"/tags/cad/","section":"Tags","summary":"","title":"CAD","type":"tags"},{"content":"","date":"31 March 2026","externalUrl":null,"permalink":"/tags/pixhawk/","section":"Tags","summary":"","title":"Pixhawk","type":"tags"},{"content":"","date":"31 March 2026","externalUrl":null,"permalink":"/tags/raspbery-pi/","section":"Tags","summary":"","title":"Raspbery Pi","type":"tags"},{"content":"","date":"31 March 2026","externalUrl":null,"permalink":"/tags/servo-motor/","section":"Tags","summary":"","title":"Servo Motor","type":"tags"},{"content":" Overview This is a teleoperated transformer robot that can switch between flight and ground modes. I started with an F450 drone frame and designed a hinge mechanism on each arm: when the arms are straight, the robot flies as a quadcopter powered by brushless motors; when the arms fold down, it becomes a wheeled ground vehicle with wheels driven by mini servo motors. The folding itself is also actuated by servo motors.\nYour browser cannot play this video. Download video.\nFull System Architecture: CAD Models: Full Assembly \u0026#8592; Aerial Mode Ground Mode \u0026#8594; Hinge Mechanism \u0026#8592; Hinge Mechanism Hinge Mechanism Hinge Mechanism with the Motors Hinge Mechanism Side View Hinge Mechanism Side View \u0026#8594; Planetary Gear-like system for wheels\n\u0026#8592; Side View Top View \u0026#8594; Design Iterations These are some of the iterations I went through before finalizing the design.\nConceptual Hinge Mechanism\n\u0026#8592; view 1 view 2 view 3 \u0026#8594; Wheel Assembly\nI initially mounted the wheel directly on the motor body, but the inertia on the brushless motors was too much and the wheels could not reach a reasonable RPM. This is why I designed a planetary gear-like system to decouple the wheel from the motor.\n\u0026#8592; v1 Full Assembly v1 Isometric v2 Full Assembly v2 Isometric \u0026#8594; Wheel Design\n\u0026#8592; v1 v2 v3 v4 v5 \u0026#8594; Flight Testing I tested the drone with both 3S and 4S batteries. With a 3S, it can carry up to 250g and hover properly, but struggles to gain altitude beyond 366g. Switching to a 4S significantly improved performance, with a payload capacity of up to 750g.\nStable Hover Your browser cannot play this video. Download video.\n","date":"31 March 2026","externalUrl":null,"permalink":"/posts/transformer-robot/","section":"Posts","summary":"Overview This is a teleoperated transformer robot that can switch between flight and ground modes. I started with an F450 drone frame and designed a hinge mechanism on each arm: when the arms are straight, the robot flies as a quadcopter powered by brushless motors; when the arms fold down, it becomes a wheeled ground vehicle with wheels driven by mini servo motors. The folding itself is also actuated by servo motors.\n","title":"Teleoperated Ground-Air Morphing Robot","type":"posts"},{"content":"","date":"31 March 2026","externalUrl":null,"permalink":"/tags/uav/","section":"Tags","summary":"","title":"UAV","type":"tags"},{"content":"","date":"22 March 2026","externalUrl":null,"permalink":"/tags/circle-fitting/","section":"Tags","summary":"","title":"Circle Fitting","type":"tags"},{"content":"","date":"22 March 2026","externalUrl":null,"permalink":"/tags/ekf-slam/","section":"Tags","summary":"","title":"EKF SLAM","type":"tags"},{"content":" Overview Built a complete EKF SLAM pipeline from scratch in C++ using ROS 2, simulated on a TurtleBot3. The robot localizes itself and maps cylindrical landmarks simultaneously using wheel odometry and 2D LiDAR. Three robots are visualized: red (ground truth, known only to the simulator), blue (odometry estimate, which drifts over time), and green (SLAM corrected estimate). The video shows the robot driving a closed path with sensor noise and limited detection range. As odometry drifts, the EKF corrects it by fusing landmark observations, keeping the green path close to ground truth while blue diverges. Landmark estimates in green converge toward their true positions with repeated observations.\nYour browser cannot play this video. Download video.\nROS 2 Package Breakdown turtlelib: Standalone C++ library for 2D rigid body transforms, SE(2) geometry, twist integration, and differential drive kinematics. No ROS dependency.\nnuturtle_description: Custom URDF/Xacro for TurtleBot3 with configurable wheel radius, track width, and collision geometry. Supports multiple color coded robots for simultaneous visualization.\nnusim: Simulation node that models the robot\u0026rsquo;s environment including wheel slip, Gaussian sensor noise, obstacle collision detection, fake landmark sensing, and simulated 2D LiDAR via circle line intersection.\nnuturtle_control Converts twist commands to wheel velocities, publishes odometry from encoder data, and provides a circle driving node for testing. Includes integration tests using catch_ros2.\nnuslam: The SLAM package. Runs the Extended Kalman Filter with unknown data association via Mahalanobis distance. Contains a landmark detection node that clusters LiDAR points, fits circles using regression, and classifies valid landmarks using the inscribed angle theorem.\nLandmark Detection Your browser cannot play this video. Download video.\nThe landmark detection node takes raw 2D LaserScan data and extracts cylindrical landmarks. First, scan points are clustered based on a distance threshold between consecutive readings, wrapping around the full scan. Clusters with fewer than 3 points are discarded. Each remaining cluster is passed through a circle fitting regression algorithm to estimate the center and radius. Clusters are then classified as circle or not circle using the inscribed angle theorem: if the standard deviation of inscribed angles is low and the mean angle falls within a valid range, the cluster is accepted as a landmark. Circles with unreasonable radii are filtered out as a final sanity check.\nSimulated Sensor Data Your browser cannot play this video. Download video.\nThe simulator generates fake sensor data to test the SLAM pipeline without a physical robot. Landmark positions are published relative to the robot at 5 Hz with Gaussian noise, and landmarks beyond a configurable max range are hidden. A simulated LiDAR publishes a full LaserScan by raycasting against obstacles and arena walls using circle line intersection, also with Gaussian noise on each range reading. Wheel commands are corrupted with input noise and random slip per wheel, so encoder readings diverge from true motion over time, forcing the EKF to rely on landmark corrections.\nOdometry and Control Your browser cannot play this video. Download video.\nThe video shows the TurtleBot3 driving in circles both in simulation and on the physical robot. In simulation, the blue (odometry) and red (ground truth) robots overlap perfectly since there is no noise or slip. On the real robot, the blue robot gradually drifts from the actual position as odometry error accumulates over repeated loops. The final odometry pose after returning to the start position gives a measure of the cumulative drift.\nDemo on Turtlebot Your browser cannot play this video. Download video.\n","date":"22 March 2026","externalUrl":null,"permalink":"/posts/slam/","section":"Posts","summary":"Overview Built a complete EKF SLAM pipeline from scratch in C++ using ROS 2, simulated on a TurtleBot3. The robot localizes itself and maps cylindrical landmarks simultaneously using wheel odometry and 2D LiDAR. Three robots are visualized: red (ground truth, known only to the simulator), blue (odometry estimate, which drifts over time), and green (SLAM corrected estimate). The video shows the robot driving a closed path with sensor noise and limited detection range. As odometry drifts, the EKF corrects it by fusing landmark observations, keeping the green path close to ground truth while blue diverges. Landmark estimates in green converge toward their true positions with repeated observations.\n","title":"EKF SLAM with unknown data association","type":"posts"},{"content":"","date":"22 March 2026","externalUrl":null,"permalink":"/tags/mahalanobis-data-association/","section":"Tags","summary":"","title":"Mahalanobis Data Association","type":"tags"},{"content":"","date":"22 March 2026","externalUrl":null,"permalink":"/tags/mapping/","section":"Tags","summary":"","title":"Mapping","type":"tags"},{"content":"","date":"22 March 2026","externalUrl":null,"permalink":"/tags/turtlebot-robot/","section":"Tags","summary":"","title":"Turtlebot Robot","type":"tags"},{"content":"","date":"12 December 2025","externalUrl":null,"permalink":"/tags/dynamics/","section":"Tags","summary":"","title":"Dynamics","type":"tags"},{"content":"","date":"12 December 2025","externalUrl":null,"permalink":"/tags/franka-arm/","section":"Tags","summary":"","title":"Franka Arm","type":"tags"},{"content":" Outer Box Frames The frame at the center of the outer box is obtained by translating the world frame to the box center and then rotating it by the box orientation \\(\\theta_{\\text{box}}\\).\nJack Frames The frame at the center of the jack is obtained by translating the world frame to the jack center and then rotating it by the jack orientation \\(\\theta_{\\text{jack}}\\). The corner positions are defined relative to the jack center (fixed offsets), rotated by \\(\\theta_{\\text{jack}}\\), and then expressed in the box frame.\nKinetic Energy and Potential Energy From the box and jack center frames, I compute the coordinates and their derivatives and use them to calculate kinetic and potential energy.\nKinetic energies are $$T_{\\text{box}} = \\frac{1}{2} M (\\dot{x}^2 + \\dot{y}^2) + \\frac{1}{2} J \\omega^2,$$ $$T_{\\text{jack}} = \\frac{1}{2} m (\\dot{x}^2 + \\dot{y}^2) + \\frac{1}{2} j \\omega^2.$$and the gravitational potential energies are $$V_{\\text{box}} = M g y, \\qquad V_{\\text{jack}} = m g y,$$ where \\(y\\) is the vertical position of the corresponding center of mass.\nSystem Variables and Euler–Lagrange Equations The system variables are \\([x_{\\text{box}}, y_{\\text{box}}, \\theta_{\\text{box}}, x_{\\text{jack}}, y_{\\text{jack}}, \\theta_{\\text{jack}}].\\)\nThe Lagrangian is defined as the difference between the total kinetic and total potential energy, $$L = T_{\\text{box}} + T_{\\text{jack}} - (V_{\\text{box}} + V_{\\text{jack}}).$$The Euler–Lagrange equation is $$-\\frac{\\partial L}{\\partial q} + \\frac{d}{dt} \\left( \\frac{\\partial L}{\\partial \\dot{q}} \\right) = F,$$ where \\(q\\) is the vector of system variables and \\(F\\) is the force vector.\nConstraints The motion is constrained so that all jack corners remain inside the outer box:\n$$x_{\\text{box}} - \\frac{L}{2} \u003c x_{\\text{corner}} \u003c x_{\\text{box}} + \\frac{L}{2},$$ $$y_{\\text{box}} - \\frac{L}{2} \u003c y_{\\text{corner}} \u003c y_{\\text{box}} + \\frac{L}{2}.$$A ground constraint is also applied so that the box does not move below the floor: $$y_{\\text{box}} \\geq \\frac{L}{2}.$$ External Force and Torque To make the system move, the box is given a desired angle that changes with time, $$\\theta_{\\text{desired}}(t) = \\frac{\\pi}{15} + \\frac{\\pi}{3} \\sin^3\\left(\\frac{t}{2}\\right).$$A torque is applied to the box that tries to make its actual angle \\(\\theta_{\\text{box}}\\) follow this desired angle, $$\\tau_{\\text{box}} = -15\\,\\big(\\theta_{\\text{desired}} - \\theta_{\\text{box}}\\big).$$Because the jack is connected to the box, it feels a restoring torque, $$\\tau_{\\text{jack}} = -\\frac{j}{J} \\, \\tau_{\\text{box}}.$$In the vertical direction, the box is given a constant downward force \\(F_{\\text{box}} = M a\\), producing a vertical acceleration \\(a\\). A corresponding constant force \\(F_{\\text{jack}} = -m a\\) is applied to the jack in the opposite direction, using the same acceleration \\(a\\).\nSo, the resulting force vector is as follows: $$F = [0, F_{\\text{box}}, \\tau_{\\text{box}}, 0, F_{\\text{jack}}, \\tau_{\\text{jack}}].$$ Active Constraints and Impact During the simulation, each constraint \\(\\phi_i(q)\\) is evaluated at every time step. A constraint is treated as active when $$|\\phi_i(q)| \u003c \\varepsilon,$$ and inactive constraints use \\(\\lambda_i = 0\\).\nWhen an active constraint indicates contact, I resolve a single dominant impact for that time step by enforcing constraint consistency and momentum balance.\nGraphs ","date":"12 December 2025","externalUrl":null,"permalink":"/posts/jack-in-the-box/","section":"Posts","summary":"Outer Box Frames The frame at the center of the outer box is obtained by translating the world frame to the box center and then rotating it by the box orientation \\(\\theta_{\\text{box}}\\).\n","title":"Jack-in-the-Box","type":"posts"},{"content":"","date":"12 December 2025","externalUrl":null,"permalink":"/tags/moveit/","section":"Tags","summary":"","title":"Moveit","type":"tags"},{"content":" This was a group project by Halley Zhong, Nolan Knight, Miguel, and myself for Northwestern\u0026rsquo;s MECH_ENG 450: Embedded Systems in Robotics course. We built an autonomous system to sort moving HexBugs using the Franka Arm. My role was to develop the vision system, which can detect, uniquely label, and track the moving bugs in real time.\nThe robot is controlled through the MotionPlanningInterface, which has three main components:\nRobotState – keeps track of the robot’s current position. MotionPlanner – plans safe movements for the robot. PlanningScene – monitors obstacles to prevent collisions. On top of this, the TargetDecision and Sort nodes use the vision system to locate colored bugs, decide which one to pick next, and move it to its designated spot.\nBecause the HexBugs move in real time, the system can bypass MoveIt and control the robot joints directly using the fer_arm_controller. This allows the Franka Arm to follow moving targets smoothly and efficiently.\n","date":"12 December 2025","externalUrl":null,"permalink":"/posts/mrs-catfisher/","section":"Posts","summary":" This was a group project by Halley Zhong, Nolan Knight, Miguel, and myself for Northwestern’s MECH_ENG 450: Embedded Systems in Robotics course. We built an autonomous system to sort moving HexBugs using the Franka Arm. My role was to develop the vision system, which can detect, uniquely label, and track the moving bugs in real time.\n","title":"Mrs. Catfisher - The Bug Sorter","type":"posts"},{"content":"","date":"12 December 2025","externalUrl":null,"permalink":"/tags/onshape/","section":"Tags","summary":"","title":"Onshape","type":"tags"},{"content":"","date":"12 December 2025","externalUrl":null,"permalink":"/tags/opencv/","section":"Tags","summary":"","title":"OpenCV","type":"tags"},{"content":"","date":"11 September 2025","externalUrl":null,"permalink":"/tags/rrt-algorithm/","section":"Tags","summary":"","title":"RRT Algorithm","type":"tags"},{"content":" An RRT is a set of vertices (configurations) and edges (connections between configurations). Each iteration samples a random point in the domain, finds the nearest existing vertex, and takes a small step of size \\(\\Delta\\) toward the sample. If you run it for long enough, you get close to uniform coverage over the whole space.\nSimple RRT For implementing a Simple RRT:\nDomain: $D = [0,100] \\times [0,100]$ Initial configuration: $q_{\\text{init}} = (50, 50)$ Step size: $\\Delta = 1$ At each iteration, the following steps are performed\nSample a random point $q_{\\text{rand}}$ for $x$ and $y$. Find the nearest vertex $q_{\\text{near}}$ by looping through all vertices in $G$ and taking the one with minimum Euclidean distance. Compute the unit direction vector from $q_{\\text{near}}$ to $q_{\\text{rand}}$ and step by $\\Delta=1$ to get $q_{\\text{new}}$: $$q_{\\text{new}} = q_{\\text{near}} + \\Delta\\,\\frac{q_{\\text{rand}} - q_{\\text{near}}}{\\lVert q_{\\text{rand}} - q_{\\text{near}} \\rVert}.$$ Add $q_{\\text{new}}$ to $G$ and plot the edge $(q_{\\text{near}}, q_{\\text{new}})$ as it grows (I used interactive plotting with a small pause each iteration). Running this for $K=1000$ iterations produces a tree that spreads outward from the start and begins to fill the entire domain. As the number of samples increases, the RRT provides increasingly uniform coverage of the free space.\nRRT with circular obstacles For this circular obstacles are added and a new vertex is only accepted if the edge from $q_{\\text{near}}$ to $q_{\\text{new}}$ is collision-free.\nCollision checking Before adding $q_{\\text{new}}$, check whether the line segment $(q_{\\text{near}}, q_{\\text{new}})$ intersects any obstacle circle. If it collides, ignore that sample and continue.\nGoal connection + path extraction After adding a new vertex, check for a collision-free straight-line connection from that vertex to the goal. If it exists, terminate and recover the path by walking parent pointers back to $q_{\\text{init}}$.\nThe final plot shows the obstacle circles, the full RRT, the start/goal, and the extracted path highlighted.\n","date":"11 September 2025","externalUrl":null,"permalink":"/posts/rrt/","section":"Posts","summary":"An RRT is a set of vertices (configurations) and edges (connections between configurations). Each iteration samples a random point in the domain, finds the nearest existing vertex, and takes a small step of size \\(\\Delta\\) toward the sample. If you run it for long enough, you get close to uniform coverage over the whole space.\n","title":"RRT for 2D Path Planning","type":"posts"},{"content":"","date":"15 October 2024","externalUrl":null,"permalink":"/tags/arduino/","section":"Tags","summary":"","title":"Arduino","type":"tags"},{"content":"","date":"15 October 2024","externalUrl":null,"permalink":"/tags/matlab/","section":"Tags","summary":"","title":"MATLAB","type":"tags"},{"content":"","date":"15 October 2024","externalUrl":null,"permalink":"/tags/solidworks/","section":"Tags","summary":"","title":"Solidworks","type":"tags"},{"content":" This was a group project done in the Vibration Lab in IIT Jodhpur, Rajasthan, India under the guidance of Prof. Barun Pratiher and Nithin Tripathi Team Members: Rishika Bera, Vellore Sahithi This project focuses on building a simulation and control system for an underwater robotic arm designed to pick and place objects in submerged environments. The system combines servo motors, a gripper, encoders, and path-planning algorithms to achieve accurate and reliable object handling. A rack and pinion mechanism is used for vertical motion, and the whole setup was tested using both physical hardware and Simulink simulations.\nHow the gripper works The gripper is controlled using a stator motor. The linear displacement of the gripper depends on the angle of rotation of the motor. A min angle is set for grasping the object and a maximum angle is set for releasing the object. The gripper was set such that there is a delay of few seconds after it grasps the object and drops it at the designated location. It was observed for every 10 degrees the gripper moves linearly by 0.5cm\nRack and Pinion setup A rack and pinion setup is used to move the gripper up and down. The servo motor rotates the pinion, which drives the rack in a straight line. Since the gripper is attached to the rack, it moves vertically based on the motor\u0026rsquo;s rotation, allowing it to align with objects at different heights.\nEncoder Motor 1 uses an incremental optical encoder, which produces pulses as the motor rotates. These pulses help measure the motor’s position and speed accurately. Motor 2 uses a Hall-effect encoder, which detects magnetic field changes from the rotating shaft to determine speed and direction, making it reliable for underwater use. Mounting the gripper The gripper is mounted on the first link of the manipulator due to weight constraints. The final setup includes the encoder linked to the first link and then to the rack and pinion casing. The end effector is attached at the end of the rack.\nFinal Demo ","date":"15 October 2024","externalUrl":null,"permalink":"/posts/underwater_manipulator/","section":"Posts","summary":" This was a group project done in the Vibration Lab in IIT Jodhpur, Rajasthan, India under the guidance of Prof. Barun Pratiher and Nithin Tripathi Team Members: Rishika Bera, Vellore Sahithi This project focuses on building a simulation and control system for an underwater robotic arm designed to pick and place objects in submerged environments. The system combines servo motors, a gripper, encoders, and path-planning algorithms to achieve accurate and reliable object handling. A rack and pinion mechanism is used for vertical motion, and the whole setup was tested using both physical hardware and Simulink simulations.\n","title":"Underwater Manipulator","type":"posts"},{"content":"","date":"29 July 2024","externalUrl":null,"permalink":"/tags/educational-technology/","section":"Tags","summary":"","title":"Educational Technology","type":"tags"},{"content":"","date":"29 July 2024","externalUrl":null,"permalink":"/tags/image-attribute-extraction/","section":"Tags","summary":"","title":"Image Attribute Extraction","type":"tags"},{"content":"","date":"29 July 2024","externalUrl":null,"permalink":"/tags/llm/","section":"Tags","summary":"","title":"LLM","type":"tags"},{"content":"","date":"29 July 2024","externalUrl":null,"permalink":"/tags/multimodal-learning/","section":"Tags","summary":"","title":"Multimodal Learning","type":"tags"},{"content":"This was the poster for the Summer Undergrad Research Internship I did at Purdue University, West Lafayette, where I received the SURF fellowship.\n","date":"29 July 2024","externalUrl":null,"permalink":"/posts/primer_curator/","section":"Posts","summary":"This was the poster for the Summer Undergrad Research Internship I did at Purdue University, West Lafayette, where I received the SURF fellowship.\n","title":"Primer Curator","type":"posts"},{"content":"","date":"29 July 2024","externalUrl":null,"permalink":"/tags/tutorial-generation/","section":"Tags","summary":"","title":"Tutorial Generation","type":"tags"},{"content":"","date":"29 July 2024","externalUrl":null,"permalink":"/tags/video-segmentation/","section":"Tags","summary":"","title":"Video Segmentation","type":"tags"},{"content":"","date":"29 July 2024","externalUrl":null,"permalink":"/tags/web-scraping/","section":"Tags","summary":"","title":"Web Scraping","type":"tags"},{"content":" Rishika Bera M.S. in Robotics @ Northwestern\nHi! I\u0026rsquo;m Rishika, a graduate student in the M.S. Robotics program at Northwestern University. I completed my B.Tech in Mechanical Engineering from IIT Jodhpur, and I\u0026rsquo;m passionate about developing intelligent robotic solutions with a focus on LLMs and autonomous systems.\nSkills ROS 2 MoveIt 2 SLAM Python C++ PyTorch Deep Learning Reinforcement Learning LLMs Computer Vision UAV CAD SolidWorks Download my resume as a PDF.\nEducation MS in Robotics Northwestern University Sep 2025 – Aug 2026 · Evanston, IL\nRobotic Manipulation System Dynamics SLAM Deep Learning Embedded AI Generative AI B.Tech in Mechanical Engineering Indian Institute of Technology – Jodhpur Dec 2021 – May 2025 · Rajasthan, India\nClassical Control Theory Kinematics \u0026 Dynamics Vibrations Thermodynamics Fluid Mechanics Work Experience Summer Undergraduate Research (SURF) Intern Purdue University May 2024 – Jul 2024 · West Lafayette, IN\nBuilt a multimodal pipeline that scrapes, categorizes, and filters text, image, and video data using the ChatGPT API for relevance scoring Developed a video segmentation module to extract relevant clips and filter irrelevant content Implemented LLM-driven image attribute extraction achieving greater than 96% classification accuracy ","externalUrl":null,"permalink":"/about/","section":"Rishika Bera","summary":" Rishika Bera M.S. in Robotics @ Northwestern\nHi! I’m Rishika, a graduate student in the M.S. Robotics program at Northwestern University. I completed my B.Tech in Mechanical Engineering from IIT Jodhpur, and I’m passionate about developing intelligent robotic solutions with a focus on LLMs and autonomous systems.\n","title":"About","type":"page"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"Download PDF\n","externalUrl":null,"permalink":"/resume/","section":"Rishika Bera","summary":"Download PDF\n","title":"Resume","type":"page"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]