
{"id":8069,"date":"2024-06-26T06:50:25","date_gmt":"2024-06-26T06:50:25","guid":{"rendered":"https:\/\/dyor.webs.upv.es\/?p=8069"},"modified":"2024-06-26T06:50:25","modified_gmt":"2024-06-26T06:50:25","slug":"english-reverse-engineering-of-tamyia-fighter","status":"publish","type":"post","link":"https:\/\/dyor.webs.upv.es\/en\/english-reverse-engineering-of-tamyia-fighter\/","title":{"rendered":"Reverse Engineering of Tamyia Fighter"},"content":{"rendered":"<p><\/p>\n<p aria-level=\"1\">At the heart of our university project lies the transformation of a childhood toy &#8211; a remote control car &#8211; into a autonomous robot capable of navigating its environment using sensors and algorithms. We repurposed existing hardware.<\/p>\n<p aria-level=\"1\"><!--more--><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Analyzing preexisting parts and RC car prework<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:360,&quot;335559739&quot;:80,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h2>\n<p aria-level=\"1\">Our first step was to thoroughly analyze the remote control car. We identified its electronic components and assessed the feasibility of integrating sensors for autonomous functionality. Understanding the behavior of the steering and throttle motors was crucial, as it laid the groundwork for our algorithm design. <span data-contrast=\"auto\">With the initial setup this was not yet possible. The car would also not operate with the remote. Initially our thought was that the speed controller wasn\u2019t working correctly. The motor kept beeping after the electricity was turned on. This usually suggests that the motor is lacking any information and control input.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">We ordered a new electronic speed control for the car and tested it again but with no success. The electrician at UPV proved to be very helpful and after spending quite a bit of time at the lab we could finally figure out that in fact a faulty battery was the problem, and the speed control was working fine. With a new battery the motor stopped beeping and as explained in the following chapter we could conduct some first tests.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">The RC-car was built around 2005 by Tamiya, a manufacturer that still exists today and has a small but dedicated fanbase. All components are modular and rather standard so it should be a great base to start with for our robot. The car is the Tamyia Fighter with the DT02 base. The remote-control car is in a car like configuration with two motors, one for the steering axis in the front and one throttle motor in the back. The main motor is powered by a 7.2V NI-MH battery. The car is intended to be controlled remotely by a two-channel controller.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Since the robot base is quite a bit larger than the prebuild concepts and also has a larger turning radius we wanted to do something else than a line follower. Inspired by the maze solver from the Coppelia Sim lab sessions we are looking for a wall following algorithm.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\">Concept Development<\/h2>\n<p aria-level=\"1\">With insights gained from our analysis, we conceptualized a plan. Our goal was to implement a wall-following algorithm, leveraging two Time of Flight (ToF) laser sensors on each side of the car to measure distances from surrounding walls. Additionally, an ultrasonic sensor mounted at the front would detect obstacles, ensuring the car could avoid frontal collisions. The <span data-contrast=\"auto\">two Time of Flight laser sensors (VL53L0X) on each side of the base should measure the distance to the sides of the walls. The front servo should then steer towards the closer wall and try to keep a predefined distance. Additionally, an ultrasonic sensor mounted at the front would detect obstacles, ensuring the car could avoid frontal collisions. <\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\">Procurement and Initial Testing<\/h2>\n<p>Upon finalizing our concept, we procured the necessary electronic components. As the components arrived, we focused on assembling and connecting them to the Arduino platform. Initial tests involved verifying the functionality of the throttle and steering motors through basic control code. Concurrently, we tested the sensors to ensure they reliably provided data necessary for autonomous operation.<\/p>\n<h3 aria-level=\"1\"><span data-contrast=\"none\">Motor connection<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:360,&quot;335559739&quot;:80,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h3>\n<p><span data-contrast=\"auto\">The first tests were conducted with a simple code to test the functionality of the front steering servo and the back motor with its electronic speed control. Both worked very well and initial concerns regarding the minimal speed of the throttle motor being too high could be dismissed. The throttle motor is very powerful but with an angle setting of about 82 degrees a slow but consistent speed that will suit our task can be achieved. Thanks to the electronic speed control the back motor can be operated exactly like a servomotor.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">With both motors being operational we could very easily connect them to the Arduino and after some first tests the controls seem to work fine. Previously we were able to test the basic functions of our motors with an Arduino Nano that unfortunately didn\u2019t live long enough to encounter our sensors.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h3 aria-level=\"1\"><span data-contrast=\"none\">Arduino Sensor connection iterations\u00a0<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:360,&quot;335559739&quot;:80,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h3>\n<p><span data-contrast=\"auto\">With the Arduino Uno and the help of a bread board we were able to connect the first ToF sensor to our board and finally get some sensor readings. To get a more final connection to the Uno and reduce the number of pins in the breadboard we tried to solder the necessary connections to a blank Uno expansion shield. We created a circuit plan for the ToF sensors and how they have to be connected.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8070\" src=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-1.png\" alt=\"\" width=\"341\" height=\"292\" \/><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-8071\" src=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-1-300x288.jpg\" alt=\"\" width=\"300\" height=\"288\" srcset=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-1-300x288.jpg 300w, https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-1.jpg 600w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p><span data-contrast=\"auto\">When using only a single sensor the connection is very straightforward. You can simply connect the pins for voltage and ground, the SDA to A4 and the SCL to A4. Using multiple VL53L0X sensors with a single Arduino can be achieved by giving each sensor a unique I2C address. By default, all VL53L0X sensors have the same I2C address (0x29), so we need to change the addresses after initializing each sensor. For the circuit all SDA and SCL pins need to be connected to the same analog pins.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Unfortunately, the soldering didn\u2019t go as planned and we still couldn\u2019t conduct proper tests for our ToF sensos. After working with a newly ordered presoldered expansion shield and a big breadboard we could test the function of all sensors, get the output readings.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\"> <img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8075\" src=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-2-1-300x224.jpg\" alt=\"\" width=\"400\" height=\"299\" srcset=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-2-1-300x224.jpg 300w, https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-2-1-1024x766.jpg 1024w, https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-2-1-768x575.jpg 768w, https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-2-1.jpg 1029w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><br \/>\n<\/span><\/p>\n<p><span data-contrast=\"auto\">Even though we finally go a connection the whole setup was still very messy and as seen on the picture even with only two of our five sensor there a lot of cables used. Finally, we got our hands on a proper sensor shield with preinstalled pins for an even easier connection. This will be part of the final assembly.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h3 aria-level=\"2\"><span data-contrast=\"none\">Sensor mounting<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:160,&quot;335559739&quot;:80,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h3>\n<p><span data-contrast=\"auto\">To properly mount the sensor to our chassis our preferred method would have been to drill holes in the chassis of the char and use the M2 screw holes to tighten the sensors to the premarked positions. Due to a lack of equipment, we bought some cheap drills from the local chino market and, since they didn\u2019t work, heated them over a candle to simply melt our holes in the chassis. This worked exceptionally well and with the help of some glue and nails for pins we secured our ToF sensors in the predetermined spots. The front sonar sensor is only responsible for a wall detection to the front and doesn\u2019t have to be in precise location so it is glued to the front bumper.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\"> <img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-8076\" src=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-3-225x300.jpg\" alt=\"\" width=\"225\" height=\"300\" srcset=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-3-225x300.jpg 225w, https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-3.jpg 522w\" sizes=\"auto, (max-width: 225px) 100vw, 225px\" \/><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-8077\" src=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-4-226x300.jpg\" alt=\"\" width=\"226\" height=\"300\" srcset=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-4-226x300.jpg 226w, https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-4.jpg 522w\" sizes=\"auto, (max-width: 226px) 100vw, 226px\" \/><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-8078\" src=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-5-300x132.jpg\" alt=\"\" width=\"300\" height=\"132\" srcset=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-5-300x132.jpg 300w, https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-5-1024x451.jpg 1024w, https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-5-768x338.jpg 768w, https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-5.jpg 1060w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/span><\/p>\n<p><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\"> <img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-8079\" src=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-6-269x300.jpg\" alt=\"\" width=\"269\" height=\"300\" srcset=\"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-6-269x300.jpg 269w, https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-6.jpg 574w\" sizes=\"auto, (max-width: 269px) 100vw, 269px\" \/><\/span><\/p>\n<h3><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:0,&quot;335559740&quot;:240}\">\u00a0<\/span><span data-contrast=\"none\">Testing<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:360,&quot;335559739&quot;:80,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h3>\n<p><span data-contrast=\"auto\">After the base setup with sensors and connected motors and the first lines of code were in a working state we went to the testing phase. Our setup enabled us to gather real-time data in the Serial Monitor to understand the behavior of the code and the sensor data. Iterative coding and testing sessions allowed us to check and refine the algorithm, ensuring precise navigation and obstacle avoidance.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">One of the most critical tools for bug fixing and testing was the serial monitor that provided us live information about the current actions that the robot was taking.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h3 aria-level=\"1\"><span data-contrast=\"none\">Difficulties with components<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:360,&quot;335559739&quot;:80,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h3>\n<p><span data-contrast=\"auto\">Using older components like the ones from our car comes with its own form of challenges. First of all, two Arduinos got damaged during our testing process and we are uncertain about the cause. Potentially the front servo that was being powered through the 5V connection on the board or the connected electronic speed control are responsible for the failures, but we are uncertain. The front servo itself proved to be quite problematic too.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Its behavior was generally very inconsistent and at times its only able to steer to the right or to left. When this happened, it could find a position close to the 90 degrees angle somewhat consistently. We rechecked the servo motor behavior with simple control code and found that the input angles were not being implemented correctly on the car. With the final setup and code we could achieve a full range of motion but the distances between left and right steering seem to be inconsistent.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Initially, only two of the ToF sensors worked. We checked for wiring issues, but the sensors also failed to work with the cable connections of the functioning sensors.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">We concluded it was a soldering connection problem. After renewing the soldering connections, we received data from all five sensors: the four ToF sensors and the ultrasonic sensor at the front.\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">As long as we can set the neutral angle correctly this should only impact the behavior in the short term. The concrete steering angle values are most important for optimization.\u00a0\u00a0<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Code<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:360,&quot;335559739&quot;:80,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">First, we wrote some code to test and understand the behavior of the steering motor and the throttle motor. Next, we wrote code to test the sensors, allowing us to monitor sensor data in the serial monitor and assess its reliability. We then combined the servo motor actuation for steering with the sensor data to observe the reaction time and establish a basis for the wall-following algorithm. After this worked, we included the throttle motor actuation in the code.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h3 aria-level=\"2\"><span data-contrast=\"none\">The two sensors on each side solution<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:160,&quot;335559739&quot;:80,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h3>\n<p><span data-contrast=\"auto\">The initial idea for our code was to work with a similar concept to the robot used in our lab session for the maze solver. We have two ToF sensors on each side which give two different ranges and can thus compute or recognize the current angle to the wall. For our code we planned on giving a range during which a wall is being followed and recognized, a range of distance during which the distance is acceptable and should be kept and a range where the distance to the wall should be increased. The plan was for the robot to get the actual wall distance through the average distance between the sensors. If the distance to the wall should be increased and the difference between the sensors is equal or within a predefined range, the robot would steer away from the wall for a bit before correcting the angle by trying to get the sensor to a more equal distance again. We tried to make this code work for a long time but in the end couldn\u2019t make it work. Possible reasons include inconsistencies in the sensor data that interrupt the process without a filter, delays in the motor control, the distance between the sensors being too short and thus the difference in readings too minimal or mistakes in the codes logic.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"2\"><span data-contrast=\"none\">Final code concept and explanation<\/span><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:160,&quot;335559739&quot;:80,&quot;335559740&quot;:259}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">Our final code will be explained and displayed here. <\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<h3>Initialization<\/h3>\n<p><span data-contrast=\"none\">In the setup function, the robot initializes its sensors and motors. Each ToF sensor is assigned a unique I2C address to allow individual readings. The HC-SR04 pins are set up for triggering and reading echo signals. The robot also sets up the servo motors for steering and throttle control. Initially, all ToF sensors are disabled to avoid conflicts during initialization, and then each sensor is enabled and initialized one by one. After setting up the sensors, the robot starts moving forward by default.\u00a0<\/span><\/p>\n<h3 aria-level=\"4\"><span data-contrast=\"none\">Loops<\/span><\/h3>\n<p><span data-contrast=\"none\">The main loop of the program reads sensor data and decides the robot&#8217;s state: searching for a wall, following a wall and stopping.\u00a0<\/span><\/p>\n<ol>\n<li><span data-contrast=\"none\"><strong> Reading Sensor Data:<\/strong> The robot reads distance data from all sensors. If a reading fails, it is set to zero to ensure the robot does not act on invalid data.\u00a0<\/span><\/li>\n<li><span data-contrast=\"none\"><strong> State Transitions:<\/strong> Based on the sensor data, the robot decides which state to transition to:\u00a0<\/span><\/li>\n<\/ol>\n<ul>\n<li><span data-contrast=\"none\"><strong> SEARCH_WALL:<\/strong> The robot searches for walls on either side and transitions to &#8212;-FOLLOW_WALL if it finds one.<\/span><\/li>\n<li><span data-contrast=\"none\"><strong> FOLLOW_WALL:<\/strong> The robot adjusts its course to maintain a certain distance from the wall. It can turn left or right to stay parallel to the wall.<\/span><\/li>\n<li><span data-contrast=\"none\"><strong> STOP:<\/strong> If an obstacle is detected in front, the robot stops and waits before checking again. If there is still a wall or an obstacle in front, it drives backwards while steering to the right if there is a wall on the left and while steering to the left if there is a wall on the right.<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"none\">The robot continuously prints sensor data to the serial monitor for debugging purposes. It also checks if there is a wall in front using the sonar sensor and if there are walls on either side using the ToF sensors. Depending on the detected distances, it adjusts its state and behavior accordingly.\u00a0<\/span><\/p>\n<h3 aria-level=\"4\"><span data-contrast=\"none\">Helper Functions\u00a0<\/span><\/h3>\n<p><span data-contrast=\"none\">Several helper functions manage the robot&#8217;s movement and sensor initialization:\u00a0<\/span><\/p>\n<ul>\n<li><span data-contrast=\"none\"> moveForward(), moveBackward(): These functions control the throttle and steering to move the robot forward or backward. The moveForward() function sets the throttle for forward movement and straightens the steering. The moveBackward() function adjusts the throttle for reverse movement and steers the robot to the right.\u00a0<\/span><\/li>\n<li><span data-contrast=\"none\"> turnRight(), turnLeft(): These functions adjust the steering to turn the robot right or left while moving forward. The turnRight() function steers the robot to the right, and the turnLeft() function steers it to the left.\u00a0<\/span><\/li>\n<li><span data-contrast=\"none\"> stop(): This function stops the robot&#8217;s movement by setting the throttle to a neutral position.\u00a0<\/span><\/li>\n<li><span data-contrast=\"none\"> searchWall(): This function determines the direction to follow based on wall detection. If walls are detected on both sides, the robot decides which direction to follow based on the distances. If a wall is detected on one side only, it follows that wall. If no walls are detected, it continues to move forward while searching.\u00a0<\/span><\/li>\n<li><span data-contrast=\"none\"> followWall(): This function adjusts the robot&#8217;s course to follow the wall while maintaining a certain distance. If the robot is following a wall on the left, it adjusts its movement to keep a specified distance from the wall. If it is following a wall on the right, it does the same for the right side. If an obstacle is detected in front, it transitions to the STOP state.\u00a0<\/span><\/li>\n<\/ul>\n<h3>Problem with the trace of the vehicle<\/h3>\n<p>One specific problem we faced was related to the placement of the ultrasonic sensor. Since the sensor is mounted in the middle of the car&#8217;s front, it doesn&#8217;t cover the entire width of the car. This limitation means that the sensor can miss obstacles that are in the path of the car&#8217;s wheels, leading to situations where the car gets stuck. In these instances, the sensor detects no obstacles, but the wheels hit an object outside the sensor&#8217;s detection range.<\/p>\n<p>Here is a video demonstrating this issue:<\/p>\n<p><iframe loading=\"lazy\" title=\"Tamiya Robot Sonar Limits\" width=\"600\" height=\"338\" src=\"https:\/\/www.youtube.com\/embed\/YDqWWGbZLIM?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<h3>Our final code is the following:<\/h3>\n<div>\n<div>#include &lt;Wire.h&gt;<\/div>\n<div>#include &lt;VL53L0X.h&gt;<\/div>\n<div>#include &lt;Servo.h&gt;<\/div>\n<div>\/\/ Define pins for the HC-SR04 sensor<\/div>\n<div>const int trigPin = 8;<\/div>\n<div>const int echoPin = 9;<\/div>\n<div>\/\/ Define Servo motor<\/div>\n<div>Servo steering;<\/div>\n<div>Servo throttle;<\/div>\n<div>\/\/ Define shutdown pins for each sensor<\/div>\n<div>const int shutPin1 = 2;<\/div>\n<div>const int shutPin2 = 3;<\/div>\n<div>const int shutPin3 = 4;<\/div>\n<div>const int shutPin4 = 5;<\/div>\n<div>\/\/ Define I2C addresses for ToF sensors<\/div>\n<div>#define TOF_FRONT_LEFT_ADDRESS 0x30<\/div>\n<div>#define TOF_FRONT_RIGHT_ADDRESS 0x31<\/div>\n<div>#define TOF_REAR_LEFT_ADDRESS 0x32<\/div>\n<div>#define TOF_REAR_RIGHT_ADDRESS 0x33<\/div>\n<div>\/\/ Create VL53L0X sensor objects<\/div>\n<div>VL53L0X sensorFrontLeft;<\/div>\n<div>VL53L0X sensorFrontRight;<\/div>\n<div>VL53L0X sensorRearLeft;<\/div>\n<div>VL53L0X sensorRearRight;<\/div>\n<div>\/\/ State definitions<\/div>\n<div>enum State {<\/div>\n<div>FOLLOW_WALL,<\/div>\n<div>SEARCH_WALL,<\/div>\n<div>STOP<\/div>\n<div>};<\/div>\n<div>State currentState = SEARCH_WALL;<\/div>\n<div>void moveForward();<\/div>\n<div>void turnRight();<\/div>\n<div>void turnLeft();<\/div>\n<div>void stop();<\/div>\n<div>void moveBackward(long reverseStartTime);<\/div>\n<div>void searchWall(int &amp;direction, bool wallLeft, bool wallRight, int dFL, int dFR);<\/div>\n<div>void followWall(int dFL, int dFR, int dRL, int dRR, long dSonar, int direction, bool wallFront);<\/div>\n<div>long readSonar();<\/div>\n<div>void initializeSensor(VL53L0X &amp;sensor, int shutPin, int address);<\/div>\n<div>const int maxdistanceSonar = 50;<\/div>\n<div>const int maxdistanceSide = 220;<\/div>\n<div>const int printInterval = 2000; \/\/ Print sensor data every 2 seconds<\/div>\n<div>const unsigned long stopTimeout = 2000; \/\/ Timeout in milliseconds (2 seconds)<\/div>\n<div>const unsigned long reverseDuration = 500; \/\/ Duration for driving reverse<\/div>\n<div>unsigned long lastPrintTime = 0;<\/div>\n<div>unsigned long stopStartTime = 0; \/\/ Time when the robot entered STOP state<\/div>\n<div>unsigned long reverseStartTime = 0; \/\/ Time when the robot started driving backwards<\/div>\n<div>int direction = 0; \/\/ Follow right 1, follow left -1<\/div>\n<div>void setup() {<\/div>\n<div>\/\/ Initialize serial communication<\/div>\n<div>Serial.begin(9600);<\/div>\n<div>\/\/ Initialize the I2C bus<\/div>\n<div>Wire.begin();<\/div>\n<div>\/\/ Initialize shutdown pins<\/div>\n<div>pinMode(shutPin1, OUTPUT);<\/div>\n<div>pinMode(shutPin2, OUTPUT);<\/div>\n<div>pinMode(shutPin3, OUTPUT);<\/div>\n<div>pinMode(shutPin4, OUTPUT);<\/div>\n<div><\/div>\n<div>\/\/ Initially disable all sensors<\/div>\n<div>digitalWrite(shutPin1, LOW);<\/div>\n<div>digitalWrite(shutPin2, LOW);<\/div>\n<div>digitalWrite(shutPin3, LOW);<\/div>\n<div>digitalWrite(shutPin4, LOW);<\/div>\n<div>delay(10);<\/div>\n<div>\/\/ Enable and initialize each sensor<\/div>\n<div>initializeSensor(sensorFrontLeft, shutPin1, TOF_FRONT_LEFT_ADDRESS);<\/div>\n<div>initializeSensor(sensorFrontRight, shutPin2, TOF_FRONT_RIGHT_ADDRESS);<\/div>\n<div>initializeSensor(sensorRearLeft, shutPin3, TOF_REAR_LEFT_ADDRESS);<\/div>\n<div>initializeSensor(sensorRearRight, shutPin4, TOF_REAR_RIGHT_ADDRESS);<\/div>\n<div>\/\/ Initialize the HC-SR04 sensor pins<\/div>\n<div>pinMode(trigPin, OUTPUT);<\/div>\n<div>pinMode(echoPin, INPUT);<\/div>\n<div>\/\/ Initialize the Motors<\/div>\n<div>throttle.attach(6);<\/div>\n<div>steering.attach(10);<\/div>\n<div>\/\/ Initially move forward<\/div>\n<div>moveForward();<\/div>\n<div>}<\/div>\n<div>void loop() {<\/div>\n<div>\/\/ Read distances from the ToF sensors<\/div>\n<div>uint16_t dFL = sensorFrontLeft.readRangeContinuousMillimeters();<\/div>\n<div>uint16_t dFR = sensorFrontRight.readRangeContinuousMillimeters();<\/div>\n<div>uint16_t dRL = sensorRearLeft.readRangeContinuousMillimeters();<\/div>\n<div>uint16_t dRR = sensorRearRight.readRangeContinuousMillimeters();<\/div>\n<div>long dSonar = readSonar();<\/div>\n<div>\/\/ Handle sensor read failures<\/div>\n<div>if(dFL == 8190) dFL = 0;<\/div>\n<div>if(dFR == 8190) dFR = 0;<\/div>\n<div>if(dRL == 8190) dRL = 0;<\/div>\n<div>if(dRR == 8190) dRR = 0;<\/div>\n<div>\/\/ Print sensor data periodically<\/div>\n<div>unsignedlong currentTime = millis();<\/div>\n<div>if(currentTime &#8211; lastPrintTime &gt;= printInterval){<\/div>\n<div>Serial.print(&#8220;Sonar Distance: &#8220;);<\/div>\n<div>Serial.print(dSonar);<\/div>\n<div>Serial.print(&#8221; mm, dFL: &#8220;);<\/div>\n<div>Serial.print(dFL);<\/div>\n<div>Serial.print(&#8221; mm, dFR: &#8220;);<\/div>\n<div>Serial.print(dFR);<\/div>\n<div>Serial.print(&#8221; mm, dRL: &#8220;);<\/div>\n<div>Serial.print(dRL);<\/div>\n<div>Serial.print(&#8221; mm, dRR: &#8220;);<\/div>\n<div>Serial.println(dRR);<\/div>\n<div>lastPrintTime = currentTime;<\/div>\n<div>}<\/div>\n<div>\/\/ Determine wall following status<\/div>\n<div>bool wallFront = dSonar &lt; maxdistanceSonar;<\/div>\n<div>bool wallLeft = (dFL &lt; maxdistanceSide) || (dRL &lt; maxdistanceSide);<\/div>\n<div>bool wallRight = (dFR &lt; maxdistanceSide) || (dRR &lt; maxdistanceSide);<\/div>\n<div>switch(currentState){<\/div>\n<div>case SEARCH_WALL:<\/div>\n<div>searchWall(direction, wallLeft, wallRight, dFL, dFR);<\/div>\n<div>break;<\/div>\n<div>case FOLLOW_WALL:<\/div>\n<div>followWall(dFL, dFR, dRL, dRR, dSonar, direction, wallFront);<\/div>\n<div>break;<\/div>\n<div>case STOP:<\/div>\n<div>stop();<\/div>\n<div>if(millis() &#8211; stopStartTime &gt;= 1000){ \/\/ Check after 1 second<\/div>\n<div>wallFront = dSonar &lt; maxdistanceSonar; \/\/ Recheck for wall front<\/div>\n<div>if(!wallFront){<\/div>\n<div>currentState = SEARCH_WALL;<\/div>\n<div>moveForward();<\/div>\n<div>}elseif(wallFront){<\/div>\n<div>reverseStartTime = millis(); \/\/ Set reverse start time<\/div>\n<div>if(direction == 1){<\/div>\n<div>steering.writeMicroseconds(1300); \/\/ Steer left<\/div>\n<div>moveBackward(reverseStartTime); \/\/ The car moves backward<\/div>\n<div>}elseif(direction == -1){<\/div>\n<div>steering.writeMicroseconds(700); \/\/ Steer left<\/div>\n<div>moveBackward(reverseStartTime); \/\/ The car moves backward<\/div>\n<div>}<\/div>\n<div>}<\/div>\n<div>}<\/div>\n<div>break;<\/div>\n<div>}<\/div>\n<div>delay(50); \/\/ Delay between readings for faster reaction<\/div>\n<div>}<\/div>\n<div>\/\/ Function to read the HC-SR04 sensor<\/div>\n<div>long readSonar() {<\/div>\n<div>long duration, distance;<\/div>\n<div>digitalWrite(trigPin, LOW);<\/div>\n<div>delayMicroseconds(2);<\/div>\n<div>digitalWrite(trigPin, HIGH);<\/div>\n<div>delayMicroseconds(10);<\/div>\n<div>digitalWrite(trigPin, LOW);<\/div>\n<div>duration = pulseIn(echoPin, HIGH);<\/div>\n<div>distance = duration * 0.034 \/ 2; \/\/ Convert to distance in cm<\/div>\n<div>return distance;<\/div>\n<div>}<\/div>\n<div>void initializeSensor(VL53L0X &amp;sensor, int shutPin, int address) {<\/div>\n<div>Serial.print(&#8220;Enabling sensor on pin &#8220;);<\/div>\n<div>Serial.println(shutPin);<\/div>\n<div>digitalWrite(shutPin, HIGH);<\/div>\n<div>delay(10);<\/div>\n<div>if(!sensor.init()){<\/div>\n<div>Serial.print(&#8220;Failed to detect and initialize sensor on pin &#8220;);<\/div>\n<div>Serial.println(shutPin);<\/div>\n<div>while(1);<\/div>\n<div>}<\/div>\n<div>Serial.println(&#8220;Sensor initialized.&#8221;);<\/div>\n<div>sensor.setAddress(address);<\/div>\n<div>sensor.setTimeout(500);<\/div>\n<div>sensor.startContinuous();<\/div>\n<div>}<\/div>\n<div>void moveForward() {<\/div>\n<div>throttle.write(80); \/\/Forwards<\/div>\n<div>steering.writeMicroseconds(1000); \/\/ Straighten the steering<\/div>\n<div>Serial.println(&#8220;Moving forward&#8221;);<\/div>\n<div>}<\/div>\n<div>void moveBackward(long reverseStartTime) {<\/div>\n<div>throttle.write(100); \/\/ Backwards<\/div>\n<div>Serial.println(&#8220;Moving backward&#8221;);<\/div>\n<div>if(millis() &#8211; reverseStartTime &gt;= reverseDuration){<\/div>\n<div>stop(); \/\/ Stop the car before changing direction<\/div>\n<div>moveForward();<\/div>\n<div>currentState = SEARCH_WALL;<\/div>\n<div>}<\/div>\n<div>}<\/div>\n<div>void searchWall(int &amp;direction, bool wallLeft, bool wallRight, int dFL, int dFR ) {<\/div>\n<div>\/\/ If a wall is detected on either side, transition to FOLLOW_WALL state<\/div>\n<div>if(wallLeft &amp;&amp; wallRight){<\/div>\n<div>direction = (dFR &lt; dFL) ? -1 : 1;<\/div>\n<div>currentState = FOLLOW_WALL;<\/div>\n<div>Serial.print(&#8220;Search wall result: Walls detected on both sides, following &#8220;);<\/div>\n<div>Serial.println(direction == 1 ? &#8220;left&#8221; : &#8220;right&#8221;);<\/div>\n<div>}elseif(wallLeft){<\/div>\n<div>currentState = FOLLOW_WALL;<\/div>\n<div>direction = 1;<\/div>\n<div>Serial.print(&#8220;Search wall result: Wall on the left, direction: &#8220;);<\/div>\n<div>Serial.println(direction);<\/div>\n<div>}elseif(wallRight){<\/div>\n<div>currentState = FOLLOW_WALL;<\/div>\n<div>direction = -1;<\/div>\n<div>Serial.print(&#8220;Search wall result: Wall on the right, direction: &#8220;);<\/div>\n<div>Serial.println(direction);<\/div>\n<div>}else{<\/div>\n<div>\/\/ Continue searching for a wall (move forward)<\/div>\n<div>direction = 0;<\/div>\n<div>moveForward();<\/div>\n<div>Serial.print(&#8220;No wall detected, still state search wall, direction: &#8220;);<\/div>\n<div>Serial.println(direction);<\/div>\n<div>}<\/div>\n<div>}<\/div>\n<div>void followWall(int dFL, int dFR, int dRL, int dRR, long dSonar, int direction, bool wallFront) {<\/div>\n<div>\/\/ If an obstacle is detected in front, transition to STOP state<\/div>\n<div>if(wallFront){<\/div>\n<div>stopStartTime = millis();<\/div>\n<div>currentState = STOP;<\/div>\n<div>return;<\/div>\n<div>}<\/div>\n<div>\/\/ Follow the wall on the left side<\/div>\n<div>if(direction == 1){<\/div>\n<div>if((dFL &gt;= 160 &amp;&amp; dFL &lt;= 200) &amp;&amp; (dRL &gt;= 160 &amp;&amp; dRL &lt;= 200)){ \/\/150-200<\/div>\n<div>moveForward();<\/div>\n<div>Serial.println(&#8220;Wall Left, Distance big enough, drive forward&#8221;);<\/div>\n<div>}elseif(dFL &gt; 200 || dRL &gt; 200){\/\/200<\/div>\n<div>turnLeft();<\/div>\n<div>Serial.println(&#8220;Wall Left, Distance too large, turn left&#8221;);<\/div>\n<div>}elseif(dFL &lt; 160 || dRL &lt; 160){\/\/150<\/div>\n<div>turnRight();<\/div>\n<div>Serial.println(&#8220;Wall Left, Distance too small, turn right&#8221;);<\/div>\n<div>}<\/div>\n<div>}<\/div>\n<div>\/\/ Follow the wall on the right side<\/div>\n<div>elseif(direction == -1){<\/div>\n<div>if((dFR &gt;= 150 &amp;&amp; dFR &lt;= 200) &amp;&amp; (dRR &gt;= 150 &amp;&amp; dRR &lt;= 200)){<\/div>\n<div>moveForward();<\/div>\n<div>Serial.println(&#8220;Wall Right, Distance big enough, drive forward&#8221;);<\/div>\n<div>}elseif(dFR &gt; 200 || dRR &gt; 200){<\/div>\n<div>turnRight();<\/div>\n<div>Serial.println(&#8220;Wall Right, Distance too large, turn right&#8221;);<\/div>\n<div>}elseif(dFR &lt; 150 || dRR &lt; 150){<\/div>\n<div>turnLeft();<\/div>\n<div>Serial.println(&#8220;Wall Right, Distance too small, turn left&#8221;);<\/div>\n<div>}<\/div>\n<div>}<\/div>\n<div>}<\/div>\n<div>void stop() {<\/div>\n<div>throttle.write(90);<\/div>\n<div>Serial.println(&#8220;Obstacle detected, stopping.&#8221;);<\/div>\n<div>}<\/div>\n<div>void turnRight() {<\/div>\n<div>throttle.write(80);<\/div>\n<div>steering.writeMicroseconds(900); \/\/ Steer right<\/div>\n<div>Serial.println(&#8220;Steering right&#8221;);<\/div>\n<div>}<\/div>\n<div>void turnLeft() {<\/div>\n<div>throttle.write(80);<\/div>\n<div>steering.writeMicroseconds(1100); \/\/ Steer left<\/div>\n<div>Serial.println(&#8220;Steering left&#8221;);<\/div>\n<div>}<\/div>\n<\/div>\n<h1>Final result<\/h1>\n<p>In the following video you can see the final result:<\/p>\n<p><iframe loading=\"lazy\" title=\"Tamiya Robot Wall Follower\" width=\"600\" height=\"338\" src=\"https:\/\/www.youtube.com\/embed\/tzvSHUgoYdE?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<p>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>At the heart of our university project lies the transformation of a childhood toy &#8211; a remote control car &#8211; into a autonomous robot capable of navigating its environment using sensors and algorithms. We repurposed existing hardware.<\/p>\n","protected":false},"author":992,"featured_media":8075,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[81],"tags":[],"class_list":["post-8069","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Picture-2-1.jpg","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":5026,"url":"https:\/\/dyor.webs.upv.es\/en\/dyor-christian\/","url_meta":{"origin":8069,"position":0},"title":"DYOR &#8211; Christian","author":"Enea","date":"Wednesday June  5th, 2019","format":false,"excerpt":"In this entry, I\u2019ll describe Christian, my robot made with an Arduino Nano, sensors and actuators and the mobile app I developed to control it. DYOR-Christian Design The robot design was made using Solidworks and the whole block that defines the robot structure was obtained from an aluminium sheet by\u2026","rel":"","context":"In &quot;Blog&quot;","block_context":{"text":"Blog","link":"https:\/\/dyor.webs.upv.es\/en\/category\/blog\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2019\/06\/robot_square.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2019\/06\/robot_square.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2019\/06\/robot_square.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2019\/06\/robot_square.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2019\/06\/robot_square.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2019\/06\/robot_square.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":7345,"url":"https:\/\/dyor.webs.upv.es\/en\/english-dyor-mobile-robotics-report\/","url_meta":{"origin":8069,"position":1},"title":"DYOR: Mobile Robotics Report","author":"dmschonh","date":"Friday June 30th, 2023","format":false,"excerpt":"In this post entry we explain our mobile robotics work assigment. The Design of the robot We assembled the robot by our own by buying the parts separately. Our robot consists of: Two steerable wheels with motors (no servomotors) and a caster wheel Two infrared sensors (obstacle detection) IR line\u2026","rel":"","context":"In &quot;Blog&quot;","block_context":{"text":"Blog","link":"https:\/\/dyor.webs.upv.es\/en\/category\/blog\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2023\/06\/20230625_151744-1-scaled.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2023\/06\/20230625_151744-1-scaled.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2023\/06\/20230625_151744-1-scaled.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2023\/06\/20230625_151744-1-scaled.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2023\/06\/20230625_151744-1-scaled.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2023\/06\/20230625_151744-1-scaled.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":7869,"url":"https:\/\/dyor.webs.upv.es\/en\/english-goleador9000\/","url_meta":{"origin":8069,"position":2},"title":"Goleador9000","author":"P592630506","date":"Wednesday June 26th, 2024","format":false,"excerpt":"The goal is to develop the Goleador9000, a mobile robot capable of moving in any direction, raising and lowering its arms, displaying various emotions, following a black line, detecting obstacles, and performing a dance routine \u00a0 DYOR \u2013 Goleador9000 Goleador adjective \u00a0\/\u0261o\u2019lea\u00f0o\u027e\/\u00a0(also\u00a0goleadora\u00a0\/\u0261o\u2019lea\u00f0o\u027ea\/) SPORT (ES) \u2013 de un equipo que consigue\u2026","rel":"","context":"In &quot;Blog&quot;","block_context":{"text":"Blog","link":"https:\/\/dyor.webs.upv.es\/en\/category\/blog\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Goleador-Front-scaled.jpeg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Goleador-Front-scaled.jpeg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Goleador-Front-scaled.jpeg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Goleador-Front-scaled.jpeg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Goleador-Front-scaled.jpeg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/Goleador-Front-scaled.jpeg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":7931,"url":"https:\/\/dyor.webs.upv.es\/en\/english-beer-pong-robot\/","url_meta":{"origin":8069,"position":3},"title":"Beer Pong Robot","author":"Luca Eichler","date":"Wednesday June 26th, 2024","format":false,"excerpt":"Introduction For our Mobile Robotics project, we decided to build a robot that plays beer pong. In other terms, it should be able to throw a ping pong ball into a cup which is standing on the same flat surface as the robot. The cup is standing about 2 to\u2026","rel":"","context":"In &quot;Blog&quot;","block_context":{"text":"Blog","link":"https:\/\/dyor.webs.upv.es\/en\/category\/blog\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/step2.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/step2.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/step2.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/step2.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/step2.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":7576,"url":"https:\/\/dyor.webs.upv.es\/en\/english-dyor-pasta-python\/","url_meta":{"origin":8069,"position":4},"title":"DYOR Pasta &#8211; Python","author":"wolfihno","date":"Wednesday June 26th, 2024","format":false,"excerpt":"This post describes designing and building of Python controlled DYOR Pasta. In this post, we will explain the design and programming process of our DYOR named Pasta. This work was carried out as a part of the Mobile Robotics class. The Design The template used for the robot design was\u2026","rel":"","context":"In &quot;Blog&quot;","block_context":{"text":"Blog","link":"https:\/\/dyor.webs.upv.es\/en\/category\/blog\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/IMG_0337-scaled.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/IMG_0337-scaled.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/IMG_0337-scaled.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/IMG_0337-scaled.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/IMG_0337-scaled.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/IMG_0337-scaled.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":7882,"url":"https:\/\/dyor.webs.upv.es\/en\/english-dyor-tobias\/","url_meta":{"origin":8069,"position":5},"title":"DYOR: Tobias","author":"DasAas","date":"Wednesday June 26th, 2024","format":false,"excerpt":"The objective of this post is to provide an overview of the assignment to build a robot in the Mobile Robotics course during the spring semester of 2024. The robot is built with lowcost components and should have some functionalities like line tracking, obstacle avoidance, moving its arms, and making\u2026","rel":"","context":"In &quot;Blog&quot;","block_context":{"text":"Blog","link":"https:\/\/dyor.webs.upv.es\/en\/category\/blog\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/profil.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/profil.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/profil.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/profil.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/profil.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/dyor.webs.upv.es\/wp-content\/uploads\/2024\/06\/profil.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/dyor.webs.upv.es\/en\/wp-json\/wp\/v2\/posts\/8069","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dyor.webs.upv.es\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dyor.webs.upv.es\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dyor.webs.upv.es\/en\/wp-json\/wp\/v2\/users\/992"}],"replies":[{"embeddable":true,"href":"https:\/\/dyor.webs.upv.es\/en\/wp-json\/wp\/v2\/comments?post=8069"}],"version-history":[{"count":2,"href":"https:\/\/dyor.webs.upv.es\/en\/wp-json\/wp\/v2\/posts\/8069\/revisions"}],"predecessor-version":[{"id":8083,"href":"https:\/\/dyor.webs.upv.es\/en\/wp-json\/wp\/v2\/posts\/8069\/revisions\/8083"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dyor.webs.upv.es\/en\/wp-json\/wp\/v2\/media\/8075"}],"wp:attachment":[{"href":"https:\/\/dyor.webs.upv.es\/en\/wp-json\/wp\/v2\/media?parent=8069"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dyor.webs.upv.es\/en\/wp-json\/wp\/v2\/categories?post=8069"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dyor.webs.upv.es\/en\/wp-json\/wp\/v2\/tags?post=8069"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}