Team Status Update for 03/21/2020

This week, we met with Professor Tamal and Joe over Zoom to discuss our change in plans. Our team members will be scattered in different places: Alex will be in Connecticut, Chakara will be in Bangkok, and Jeremy will likely return to Toronto once circumstances allow. This means that our project must be able to be completed remotely, which would void any hardware or physical requirement for our project. After the Zoom meeting, Joe brought up a fantastic idea to simulate the input data we would get from our laser setup – Jeremy will be exploring options for this since he will handle most things related to modeling and rendering for the project. Alex and Chakara will start to write code for handling the camera data and Alex will specifically be doing the math to convert 2D coordinates for the laser beam into 3D world coordinates to generate the point cloud with.

Currently, the main risk would be if we can or can not efficiently and accurately simulate or laser setup, more specifically, capturing the laser data and rotation angles. Jeremy has done a fair amount of research on this part and it seems likely that it is possible. If it does not, we can move back to using a RealSense camera to capture depth maps instead. 

The main change to the system is as mentioned in the above paragraph. We are removing all hardware/physical components of the project and will be using simulated data that we will create from rendering 3D objects instead. 

Below is the updated Gantt Chart with physical component related tasks removed. 

https://docs.google.com/spreadsheets/d/1GGzn30sgRvBdlpad1TIZRK-Fq__RTBgIKN7kDVB3IlI/edit#gid=1867312600

Below is our Refocus SOW describing the steps we will take to refocus our project:

TeamB3_2D23D_Refocus_SOW

Chakara’s Status Update for 03/21/2020

This week, I spent the first half of the week traveling back to Bangkok and setting up so I did not have much time to work on the project. After meeting with Joe and Professor Tamal on Wednesday, our team would be removing the physical parts of the project and would be creating a simulation of sensor data instead. Since my main tasks of this project were all related to the physical components (rotational mechanism, circuits, platform assembly, etc), our team changed our task delegation. I would now be working closely with Alex to implement different algorithms as needed. As I only understood briefly of our algorithms, I spent this week trying to learn and understand more about them. I also worked on SOW with other team members and was responsible for updating our task list and gantt chart. 

We are currently behind schedule because of the situation of the Coronavirus outbreak. However, after this next week, we hope to catch up on our process since we’re replacing all the physical parts and calibration mechanism with simulated data. 

By next week, I hope to fully understand the main algorithms we would be using and help Alex write some parts of the code related to the testing benchmarks and algorithm to construct global point cloud from sensor data. This would also depend on the data Jeremy would be able to simulate.

Alex’s Status Update for 03/07/2020

This week our group was responsible for ordering components and setting up our work environment so we could begin implementation as soon as Spring Break ends. I was responsible for identifying that we were missing a couple required items in our order form, such as the microsd card, sd card writer, and power supply for our embedded system. We also considered availability of components that do not need to be ordered, such as wires and soldering irons to connect GPIO pins with the motor driver and to hook up the motor driver to the stepper motor. We will also require power for the stepper motor, which requires a 5V variable amp supply to the driver, which we need to figure out (the Jetson also takes 5V at ~2A, but this signal is rectified from a 120V AC wall signal). The last thing we want to do is burn our driver board, since it is not cheap and we would need to wait for additional delivery time and would lose an additional chunk of our budget. Because of this, we will prototype analogue circuits on a mini-breadboard (provided from the lab) with a potentiometer to ensure we meet the voltage and current requirements of the motor driver.

 

I have had a very busy week before mid semester break as many courses (including the one I am TAing) are rushing to gather grades for the mid-term report. I have also departed on a 10 day vacation starting Thursday morning to Europe (Norway), and will return on Tuesday the week after Spring Break, meaning I will be missing another mandatory lab session. Luckily, we have factored in Spring Break and additional margins for slack to account for this busy time of the year, and thus we are prepared to get back on top of this project after the break.

 

This week I have also been considering implementing the testing routines, so that by the time our prototype software has been completed we can get a sense of its accuracy and timing efficiency. Instead of this however, we first need to determine our intermediate data formats, such as what the partial point clouds look like before merging multiple scans or during a single scan. To provide unit testing on each software component in the pipeline, these formats must be determined so that our testing and benchmarking software understands how to interpret our results. Because of this, instead of writing the testing code first, I began planning the prototype implementation software first, to allow also Jeremy enough time to find ground-truth models for accuracy analysis.

 

When writing test prototype code, the only parts that matter to us are:

  1. Accuracy meeting our project requirements
  2. Ease of coding and simplicity

The second requirement of the prototype code is not important to the final implementation of our project, but it is important to the prototype development. This is because we do not want to waste all of our remaining resources writing code that will not be used in the final project.

 

To meet the accuracy goal, we will test our prototypes extensively. These same tests can be reused for our final GPGPU implementation, so we do not need to re-implement testing infrastructure. This also makes sense since the prototype implementation should be a “complete” implementation that does not fully meet our timing requirement. If we have trouble implementing the accuracy goal for a stage of the prototype, we may choose to implement the section directly as our final GPGPU optimized software.

 

For ease of coding, Python is unparalleled in both our team’s knowledge of it, and the amount of computation that can be expressed in small amounts of syntax. Because of this, we will choose to use Python libraries to implement the prototypes. We will also use popular Python libraries for the prototypes, since we do not want to get stuck on issues that cannot be resolved. The library we use must be open-source (to avoid licensing complications and fees), have good documentation (for ease of development), and have an active support community (for ease of debugging).

 

Because of these, and prior experience, we will be using the following Python libraries to implement our prototype pipeline:

  1. Numpy for representation and transformation of matrices
  2. Scipy for solving optimization problems on Numpy arrays
  3. OpenCV for image filters, point-in-image detection, and other calibration procedures

 

These three technologies cover our entire use-case. Once our prototype pipeline is completely implemented, we can use the Python library Numba to auto-generate GPGPU code from our pipeline. If this code is sufficient, we do not need to implement C++ by hand for the GPU. If sufficient optimizations cannot be found, then we will need to implement some sections by hand to meet our timing requirements.

 

As a summary, my next steps:

  1. Write a “formal” specification identifying how intermediate data structures are organized throughout each stage of the pipeline.
  2. Write calibration routines using Numpy and OpenCV to do intrinsic/extrinsic camera calibration using the CALTag checkerboard pattern on the rotational platform.
  3. Write global calibration parameter optimizationusing Scipy
  4. Write laser-line detection using OpenCV
  5. Write laser plane calibration using Numpy and OpenCV
  6. Write 3D scanning procedure, interfacing with the motor controller and camera in real-time. This procedure will use ray-plane intersection with Numpy. Once this is complete, we will not only have unit tests for each section, but we can do a complete integration test on a single scan (after mesh triangulation done by Jeremy)
  7. Write the integration testing code for accuracy. Unit testing procedures will have already been implemented during development for each of the above sections of the algorithm.

Chakara’s Status Update for 03/07/2020

This week I mainly was responsible for picking up different project components and making sure they work as they are supposed to. Below is a summary table of the components that arrived and have been tested. For most mechanical components, we just tested whether or not they are fragile, rotate as they are supposed to, etc. The laser is shown to have enough intensity and the camera capture quality is great. The laser is also class 3A, but as suggested by Professor Tamal, I still contacted CMU to make sure that we don’t need additional training or safety requirements or the laser (which we do not).

 

Ordered Arrived Tested Item
Yes Yes Nema 23 Stepper Motor
Yes Yes Yes 15 Inch Wooden Circle by Woodpeckers
Yes Yes Yes Swivel Turntable Lazy Susan Heavy Duty Aluminium Alloy Rotating Bearing Turntable Round Dining Table Smooth Swivel Plate for Kaleidoscopes Tabletop Serving Trade Show Displays(10 inch)
Yes Yes Yes Source One LLC 1/8 th Inch Thick 12 x 12 Inches Acrylic Plexiglass Sheet, Clear
Shaft’s Gear
Yes Yes STEPPERONLINE CNC Stepper Motor Driver 1.0-4.2A 20-50VDC 1/128 Micro-step Resolutions for Nema 17 and 23 Stepper Motor
Yes Yes Yes Lazy Dog Warehouse Neoprene Sponge Foam Rubber Sheet Rolls 15in x 60in (1/8in Thick)
Yes Yes ~ Adafruit Line Laser Diode (1057)
Yes Yes Yes Webcamera usb 8MP 5-50mm Varifocal Lens USB Camera Sony IMX179 Sensor,Webcam Support 3264X2448@15fps,UVC Compliant Webcamera Support Most OS,Focus Adjustable USB with Cameras,High Speed USB2.0 Webcams
Yes Nvidia Jetson Nano Developer Kit
Yes Yes Yes 256GB EVO Select Memory Card and Sabrent SuperSpeed 2-Slot USB 3.0 Flash Memory Card Reader

 

The main part that I tried to test were the motor and the driver board, but I didn’t want to potentially burn them, so I decided to wait until our Jetson arrives or when we borrow an Arduino with a potential mini breadboard and potentiometer (to make sure that the current going to the driver and motor are as specified by their specs). 

 

On top of this, I did more research on how to connect the motor and driver together and read more articles which use Jetson to control a stepper motor (although different models and drivers). I also talked to TechSparks about the use of their space. I would have to 3D print a gear on the shaft of the motor and all we need to do is create an STL file and estimate how many grams of 3D-printed material we would need. For the laser cutting part, I am not trained. However, I reached out to a friend outside of this class who is trained for laser-cutting and he agreed to help cut out our acrylic sheet to create our internal gear. 

 

I am currently on schedule. Luckily the parts arrived earlier than we expected even though our team ordered them a few days later than what we planned to. 

 

For next week, I would mostly be outside of the US for spring break. I would probably not be working on this project until I come back. When I come back, I hope to test out the motor and driver and start assembling the platform together so that Jeremy and Alex can see how the rotational mechanism affects the data capturing and see what adjustments we would have to make. 

Chakara’s Status Update for 2/29/2020

This week, I was mainly working on the Design Review. I was responsible for the main platform design and rotational mechanism. On top of working in parallel with other team members on the Design Review Presentation and Design Document, I was mainly responsible for ordering project components. From the Design Review Presentation, we did a tradeoff analysis and ended up with different project components that we need. From that, I started doing research on different suppliers and models of the components we need to get the most cost-efficient ones while getting the most appropriate shipping time. Below is a table of the project components we ordered this week.

 

Ordered Item Quantity Unit Price Total Price Shipping Cost Total Cost Description Expected Shipping
Yes Nema 23 Stepper Motor 1 $23.99 $23.99 $0.00 $23.99 2 Days
Yes 15 Inch Wooden Circle  1 $14.99 $14.99 $0.00 $14.99 Plywood for platform 2 Days
Yes Lazy Susan Bearing 1 $27.19 $27.19 $0.00 $27.19 2 Days
Yes Acrylic Plexiglass Sheet, Clear 1 $9.98 $9.98 $0.00 $9.98 Laser cutting for Internal Gear 2 Days
Yes STEPPERONLINE CNC Stepper Motor Driver  1 $38.99 $38.99 $0.00 $38.99 Motor Step Driver 2 Days
Yes Neoprene Sponge Foam Rubber Sheet  1 $14.80 $14.80 $0.00 $14.80 High-friction surface 2 Days
Yes Adafruit Line Laser Diode (1057) 1 $8.95 $8.95 $8.99 $17.94 Projected Laser Stripe 2 Days
Yes Webcamera usb 8MP 5-50mm Varifocal Lens  1 $76.00 $76.00 $0.00 $76.00 2 Days
Yes Nvidia Jetson Nano Developer Kit 1 $99.00 $99.00 $18.00 $117.00 3-5 Days
Yes 256GB EVO Select Memory Card  1 $42.96 $42.96 $0.00 $42.96 MicroSD card for Jetson with Reader Bundle 2 Days
Yes MicroUSB Cable (1995) 1 $9.00 $9.00 $8.99 $17.99 MicroUSB cable for Jetson 2 Days

I did not include the sources and full names of the components in the table above. For full details, please visit https://docs.google.com/spreadsheets/d/1AP4Le1eVNL51T8ovUJb9YF-H2u47EvRG4AHWqp7ULIM/edit?usp=sharing

This comes up to a total price of $401.83 including shipping. (This is the maximum cost. If we are able to order both items from DigiKey together then it would be $392.84 instead). This gives us at least $198.17 left in case we need other parts. We will still need to order wood for support of the platform later and some of the budget could be used if the laser we ordered doesn’t have the light intensity we need. 

I’m still a little behind schedule since I ordered the parts later than what our team planned for. Our team compensated for this by moving up other tasks that could be done without the parts up the schedule. We’ll be working on those tasks while waiting for the parts to come. 

As my work is mainly related to the project parts we ordered, for next week, I hope to get the parts by Thursday and started performing basic testing on them before leaving for Spring Break. While waiting for the parts during the beginning of the week, I also hope to help Alex write some testing benchmarks. 

Jeremy’s Status Update for 2/22/2020

This week I focused on some of the data pre-processing methods we will use for our algorithm. Note that the things mentioned in the first two paragraphs in this report may not be used for our current method which involves projecting a laser strip. I first looked at the geometry for converting between the data returned from a depth camera to cartesian coordinates. This involved doing some rudimentary trigonometry to get these calculations. The depth camera should return the z-distance to each pixel, but I also accounted for the case where the Intel SR305 camera would return distance from the center of the camera to the pixel instead. We will be able to see which one it is when we actually get the camera and test it on a flat surface like a flat cube. The math computed is as follows:

As mentioned in the previous status update, we were considering using an ICP (Iterative Closest Point) algorithm to combine different scans for the depth camera method and also accurately determine the angle between scans. The ICP algorithm determines the transformation between two point clouds from different angles of the object by using least squares to match duplicate points – these point clouds would be constructed by mapping the scanned pixel and depth to their corresponding 3D cartesian coordinates as shown from the math above. Similar to gradient descent, ICP works best when starting at a good starting point to avoid being stuck at local minima and also save computation time. One potential issue with ICP is that shapes like spheres or upright cylinders would have uniform point clouds across any angle – a good method to help with this risk factor is to start the ICP algorithm using the rotational data from the stepper motor, an area that Chakara has researched on this week. Essentially, we will have the rotational data from the stepper motor and then use ICP to determine the rotational difference more precisely between the two scans, then find duplicate points and combine the two point clouds this way. 

I also looked into constructing a mesh from a point cloud. The point cloud would likely be stored in a PCD (Point Cloud Data) file format. PCD files provide more flexibility and speed than other formats like STL/OBJ/PLY, and we can use the PCL (Point Cloud Library) in C++ to process this point cloud format as fast as possible. The PCL library provides many useful functions such as estimating normals and performing triangulation (constructing a triangle mesh from XYZ points and normals). Since our data will just be a list of XYZ coordinates, we can easily convert this to the PCD format to be used with the PCL library. The triangulation algorithm works by maintaining a fringe list of points from which the mesh can be grown and slowly extending the mesh out until it covers all the points. There are many tunable parameters such as size of the neighborhood for searching points to connect, maximum edge length of the triangles, as well as maximum allowed difference between normals to connect that point, which helps deal with sharp edges and outlier points. The flow of the triangulation algorithm involves estimating the normals, combining that data with the XYZ point data, initializing the search tree and other objects, then using PCL’s reconstruction method to obtain the triangle mesh object. The algorithm will output a PolygonMesh object which can be saved as an OBJ file using PCL, which is a common format for 3d printing (and tends to perform better than STL format). There will probably be many optimization opportunities or bugs/issues to be fixed with this design as it is just a basic design based on what is available in the PCL library. 

I also looked a bit into noise reduction and outlier removal for filtering the raw point cloud data. There are many papers that discuss approaches and some even use neural nets to get probability that a point is an outlier and remove it in that sense. This would require further research and trying out different methods as I don’t completely understand what the different papers are talking about just yet. There are also libraries that have their own noise reduction functions, such as the PCL library among a few others, but it is definitely better to do more research and write our own noise reduction/outlier removal algorithm for better efficiency, unless the PCL library function is already optimized for the PCD data format.

We discussed using a projected laser strip and a CCD camera to detect how this laser strip warps around the object to determine depth and generate a point cloud, so our updated pipeline is shown below.

By next week, I will be looking to completely understand the laser strip projection approach, as well as dive much deeper into noise reduction and outlier removal methods. I may also look into experimenting with triangulation from point clouds and playing around with the PCL library. My main focus will be on noise reduction/outlier removal since that is independent of our scanning sensors – it just takes in a point cloud generated from sensor data and does a bunch of computations and transformations.

 

Chakara’s Status Update for 2/22/2020

This week, on top of working in parallel with other team members to finalize our sensor, I was mainly responsible for the rotational mechanism and platform design. The individual work I did this week can be broken down into 3 main tasks. First is to design the overall design of the rotating platform. The platform would be mainly composed of the motor, a gear, a lazy susan bearing to reduce friction, a platform, a high-friction surface, an internal gear, and a support. The high-friction surface here is to simply help reduce the chance of the object slipping off-center while the platform is rotating. The support here is to give the platform itself enough height so that the motor can be put under. The motor with a gear attached to the shaft will be inside the platform. The lazy susan will be the base, and the internal gear will be attached on top of the lazy susan bearing, and the platform will be attached on the internal gear. The gear on the motor’s shaft will be connected to the internal gear, and when the motor rotates, the platform will rotate with it. Below is a rough diagram of the design. 

For the high-friction surface, I have done some research and reduced the materials down to Polyurethane foam, Isoprene rubber, Butadiene rubber, and Nitrile rubber which our team still has to analyze them together to see which one would fit our requirement best. 

 

After deciding on the rough design, I started choosing material that would work best for the platform itself. The platform will be a circular disc with a diameter of 35cm. I then did some rough estimation to compute the stress that the platform needs to be able to handle. From our maximum input object’s mass of 7kg, the maximum gravitational force that it can exert on the platform is around 68.67N. The lazy susan bearing our team might end up using has an inner diameter of around 19.5cm (or 0.0975 m radius). This would give us an area of around 0.03m2 that would not have any support. I simplified the stress analysis of this design down but it should still give a good estimation of the stress the object would apply, which is around 2300Nm. 

 

After that, I did more research on the material that would be able to handle this much stress, be cost-efficient and easily accessible, and easy to use (cut, coat, etc). I consulted with a friend in the Material Science program and we did some optimization based on cost and mass-to-stiffness ratio to narrow down the number of materials I had to do research on. Below is an image of the optimization graph. Note that we only looked into plastic and natural materials as they are easier to use and more easily accessible. The line in the second image is the optimization line. 

 

After that, I narrowed it down more to 3 materials: plywood, epoxy/hs carbon fiber, and balsa. The table belows shows the tradeoffs between different main properties that would affect our decision. Young’s modulus, specific stiffness, and yield strength are mainly to see if the material would be able to handle the amount of stress the object would exert on it or not. The price per unit volume is to keep this within our project’s contraint. The density is used to compute the mass of the platform (for computing the torque required and to stay within our Portability requirement).

 

Material Young’s Modulus (GPa) Specific Stiffness (MN.m/kg) Yield Strength (MPa) Density (kg/m3) Price per Unit Volume (USD/m3)
Plywood 3-4.5 3.98-6.06 8.1-9.9 700-800 385-488
Carbon Fiber 58-64 38.2-42.4 533-774 1490-1540 26200-31400
Balsa 0.23-0.28 0.817-1.09 0.8-1.5 240-300 1610-3230

 

From here, we can see that carbon fiber is the strongest but is very heavy and expensive and might not suit our project well. Balsa is very light but is not as strong (even if the values here are still higher than the stress I computed, it might be because of the simplified stress analysis I did). Thus, our group decides to use plywood which is strong, inexpensive, easy-to-cut, and not too heavy. With plywood, the maximum mass our of platform would just be around 0.6kg (computed using density and dimensions of the platform).

 

The final part of the main platform design is to choose the right motor for the project. The main 2 motors I looked into to rotate the platform are the servo motor and the stepper motor. A servo motor is a motor coupled with a feedback sensor to facilitate with positioning for precise velocity and acceleration. A stepper motor, on the other hand, is a motor that divides a full rotation into a number of equal steps. To figure out the motor used, I computed the torque required to rotate the platform with the maximum object size. From the density and dimensions of the platform, I computed that the plywood platform would weight around 0.64kg and carbon fiber would be around 1.2kg (I still accounted for the heaviest material and strongest material in case of a change in the future). From that I computed the moments of inertia which is around 0.024kgm2. For the input object, I used maximum size and different dimensions and shapes to cover most main and edge cases, the maximum moments of inertia computed is around 0.1575kgm2. Thus, the total maximum moments of inertia is less than 0.2kgm2. To get the torque, I also estimated the angular acceleration needed. From Alex’s computation, we need at least a rotation of 0.0033 rad per step to capture enough data to meet our accuracy requirement. Assuming that 10% of the time requirement, which is 6s, can be used for data capturing (so that we have more buffer for the algorithmic part since we don’t exactly know how complex it would actually be yet), we would get that the angular velocity is around /3rad/s. Assuming we want our motor to be able to reach that velocity fast enough (0.5s), we have an estimated acceleration of 2.094rad/s2. From here, the estimated torque needed to rotate the platform is around 0.4188Nm. Below is the rough computation made. 

Since we need a high torque and from our algorithm we would need an accurate step, the stepper motor is preferred. The two stepper motor I looked into are the NEMA 17 and NEMA 23. NEMA 17 has a holding torque of 0.45Nm, and NEMA 23 has a holding torque of 1.26Nm. Even though NEMA 17 seems like it might be enough, in my computation, I neglected the friction which would drastically affect the torque the motor has to supply. Moreover, I also neglected the energy that would be lost through using the internal gear to rotate the platform. Since NEMA 23 is not that much more expensive, I believed NEMA 23 would fit our project best. 

I’m currently still a little behind on schedule but I caught up a lot. Learning everything about stress, torque, and material took up most of my time for this week and computing different values and making sure the simplifications are not over-simplified were also a difficult task. I am a little behind in that I expected that I would have the gear and design fully drawn with dimensions written correctly. I would do that by putting in more work before the design reviews.

 

For next week, I hope to find all the specific parts for purchase and order them. I would also like to work on the design document. Once all the material and components arrive, I would start assembling the platform. 

 

Alex’s Status Update for 2/22/2020

During this week we had a breakthrough moment for the project. Instead of choosing a sensor by what we thought would be interesting, we got detailed, quantitative requirements for the sensor so it became easy to choose.

We started from our requirements. In the most extreme case, to accurately capture an object whose longest axis is 5cm, in order to meet the requirement that 90% of reconstructed points are within 2% of that 5cm, we must have points within 1mm to the ground truth model. From this, if we consider the number of samples we need across the surface, we must have accurate samples within 1mm for each direction (X, Y along the surface). Since the surface itself is a continuous signal we are sampling from, we can compute the Nyquist sampling rate as being every 0.5mm along each direction of the surface. 

Now considering the rotational mechanism, the largest radius of the object from the center of the rotating platform will be within 15cm. We need then a single rotation per data capture to be such that the amount of the surface rotated passed the sensor is less than or equal to 0.5mm. This gives us a 0.5mm / 150mm = 0.0033 radians of rotation per sample.

There are five main types of depth sensors applicable to 3D scanning available that we have deeply considered:

  1. Contact sensors, widely used in manufacturing. A Coordinate Measuring Machine (CMM) or similar may be used, which generally utilizes a probing arm to touch the sensor, and through angular rotations of the joints the coordinates of each probed area can be computed. This is a non-option for our application, both for price and the fact that we should not allow a large machine to touch timeless archeological artifacts.
  2. Time-of-flight sensors. By recording the time between sending a beam of light and receiving a reflected signal, distance can be computed to a single point. The disadvantage of this approach is that we can only measure times so precisely, and the speed of light is very fast. With a timer that has 3.3 picosecond resolution, we are still not within sub-millimeter depth resolution, which is not reasonable for this project. Time-of-flight sensors in the domain of 3D scanning are more applicable to scanning large outdoor environments.
  3. Laser triangulation sensors. The principle of such a sensor is that an emitting diode and corresponding CMOS sensor are located at slightly different angles of the device in comparison to the object, so depth can be computed by the location on the sensor the laser reflects to. Generally the position of the laser on the surface is controlled by a rotating (or pair of rotating) mirrors (https://www.researchgate.net/publication/236087175_A_Two-Dimensional_Laser_Scanning_Mirror_Using_Motion-Decoupling_Electromagnetic_Actuators). Assume that such a sensor is affordable, can easily measure with resolution of less than 0.5mm, and we do not encounter any mechanical issues. The total number of distance measurements we are required to record is (2pi / 0.0033)  * (300mm / 0.5mm) = 1142398 by our calculations above. Assuming the sensor has a sampling rate of about 10khz (common for such a sensor), 1142398 points / 10000 points per second = 114.23 seconds theoretical minimum capture time with one sensor. From our timing requirement, assume that half of our time can be attributed to data collection (30 seconds). Then, with perfect parallelization, we could achieve our goals with 114.23s / 30s = 3.80 = 4 sensors collecting concurrently. With our budget, this is not achievable. Even if we had the budget, it is possible for systematic errors in, for example, the mounted angle of a sensor, to propagate throughout our data with no course for resolution. To add another set of sensors to mitigate this error, we would be even farther out of our budget. 8 sensors * $300 per sensor (low-end price) = $2400. Note these calculations are unrelated to any mechanical components, but are directly derived from required data points. To make budget not an issue, we could choose to adopt cheaper sensors, such as those with under 1khz sampling rate. Performing the same calculations as above with 1khz sampling rate shows us that we would require 39 sensors to meet our timing requirement, which is well out of the realm of possibility (and this is not accounting for error-reduction, which may require 78 sensors!). If we did not purchase this amount of sensors, we would drastically under perform for our timing requirement. Of course, there is an alternative to single-point laser triangulation. We may use a laser stripe depth sensor, which gets the depth for points along a fixed width stripe (https://www.researchgate.net/publication/221470061_Exploiting_Mirrors_for_Laser_Stripe_3D_Scanning). This would improve our ability to meet our timing requirements significantly. Such devices are not easily available with high accuracy to consumers, but are usually intended for industry and manufacturing. Because of this, we would have the responsibility of constructing such a device. We have considered the risk of building our own sensor, and since none of our team members are experts in the fields of sensors and electronics, there is a high potential for error on the accuracy of a constructed laser stripe depth sensor. However, we are up to the task. A stripe laser sensor consists of the pair of a projected linear light source and a CCD camera. After a calibration process to determine the intrinsic camera parameters as well as the exact angle and distance between the camera and the laser projector, linear transformations may be applied to map each point from screen space to world space coordinates. Generally the issue here, even if we do construct a perfect laser stripe depth sensor, is that micro-vibrations from the environment may introduce significant jitter in the data acquisition process. Because of this, laser sensors for 3D reconstruction are generally done in tandem with alternative sources of information, such as a digital camera or structured light depth sensor, to minimize vibrational error (https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4279470/#b8-sensors-14-20041). An alternative solution is to add an additional stripe laser sensor (https://www.sciencedirect.com/science/article/pii/S1051200413001826), which would help eliminate such errors. Because of the ease of achieving sub-millimeter accuracy, and the relative independence on lighting conditions and materials that photogrammetry is harmed by, we plan on constructing a laser stripe triangular depth sensor by using an CCD camera.
  4. Digital camera. By taking multiple digital photographs from many perspectives around the object, computer vision techniques can be used to match features between pairs of images, and linear transforms can be computed to align such features. After feature alignment, and depth calculation, point clouds can be generated. Computer vision techniques to accomplish the above include Structure from Motion (SfM) and Multi-View Stereo reconstruction (MVS) (http://vision.middlebury.edu/mview/seitz_mview_cvpr06.pdf). This approach has a fundamental flaw: concavities in the object to be scanned cannot be resolved, since cameras do not capture raw depth data. Surface points within the convex hull of an object cannot be easily distinguished from points on the convex hull. This is an immediate elimination for our project, since archeological objects may have concavities, and we do not want to limit the scope of what type of objects can be captured.
  5. Structured/coded light depth sensor (RGB-D Camera). The idea of such a sensor is to project light in specific patterns on the object, and compute depth by the distortion of the patterns. Such sensing devices have become incredibly popular in the 3D reconstruction research community with the consumer availability of the Microsoft Kinect (https://www.researchgate.net/publication/233398178_Kinect_and_RGBD_Images_Challenges_and_Applications). The original Microsoft Kinect only has 320 pixels wide of depth information for a single depth image. With the upper bound of 30cm across the surface of the object, this results in 30cm/320px = 0.094cm between each pixel, which does not meet our sensor requirement of being able to detect differences within 0.5mm (0.05 cm). The newer Microsoft Kinect v2 actually uses a time-of-flight sensor, and thus does not get measurements more accurate than 1mm depth resolution. Intel RealSense has recently released new product lines for consumer and developer structured light depth sensors, that do not require industrial/manufacturing budgets. Most notably, for short range coded light depth sensing, the Intel RealSense SR305 offers 640×480 pixel depth maps, which correlates to 30cm/640px = 0.047cm, which is within our requirements. If vertical accuracy becomes a problem with the 480px, we can rotate the camera up or utilize a mirror to take two captures for each perspective. Ensuring that the capture of the camera covers most of the object, we need about 30cm distance with its minimum 66 degree horizontal camera angle, and 52 degree vertical. This works well with the camera’s minimum depth capture of 20cm. Finally, with structured light depth sensing, depth resolution is somewhat proportional to distance, so as long as our object is close to the sensor, we would hopefully achieve sub-millimeter depth resolution. Intel does not advertise any specific depth resolution for the device. We would need to perform extensive testing to discover actual depth accuracy before further implementation. Lighting environment and material of the object can also influence depth resolution, which we will investigate with a variety of objects. Compared to laser triangulation, in which most of the effort is up-front in sensing devices and mechanical components, structured light depth sensors require a significant algorithmic effort after data collection to correlate the views. We have already designed an algorithmic pipeline to go from multiple depth maps, to localized point clouds, to a global point cloud, to a triangular mesh. This heavy computation must meet our timing requirement of one minute, so we will be programming the algorithms from scratch to run on the GPU of the embedded system for the device.

A summary of our extensive sensor research this week: we have eliminated the options of contact sensors, time-of-flight sensors, and digital cameras. Both laser triangulation sensors and structured light depth sensors have promise. Because of the potential for vibrational and mechanical error for the laser triangulation sensor, we would likely need to use it in tandem with another laser triangulation sensor. As much as purchasing the Intel SR305 would speed up our development time, we do not know if it actually has sub-millimeter accuracy, which is a requirement, and as a product our project may be more cost effective if we build a laser triangulation sensor with two stripes and a CCD camera (depending on the cost of the CCD camera we may choose to buy a CMOS one instead).

Because of this, we will begin by searching for and buying a CCD camera, as well as two laser stripe projectors. From this we can begin implementing our calibration routines and discovering the accuracy of the scanner. We are mostly interested in the accuracy of the calibration routine, which will tell us the intrinsic parameters of the camera, which can be verified, and will also tell us computed distances and angles between the camera and the laser stripes, which can also be verified.

Next, we need to consider how we will evaluate the metrics and validation of our design. There are several components to the pipeline, and we will unit test each component individually, and integration test our final project’s results.

For accuracy of our sensor setup, we will verify the calibration procedure as mentioned above. We can also use early generated point clouds to determine standard deviation from plane fit, normalized RMS, the subpixel accuracy, distance accuracy and fill rate. From these values, we will be most interested in a sub-millimeter Z-accuracy, which is computed as the median of differences in depths to the actual distance of the plane. If the sensor does not achieve this goal, we may be forced to add an additional RGB-D camera to aid in data collection.

For accuracy of our software, we will write a simple sequential version of the code and ensure that for each stage of the pipeline, our results from the GPU-accelerated code match.

For accuracy of our rotating platform, we will measure that each step of rotation for the motor is equal to or less than our intended rotation of 0.0033 radians. 

For verification of our project as a whole, we will test each of the requirements. Timing can be measured by stopwatch, and price can be measured by our order receipts. Accuracy will be a mix of using known objects such as coke bottles and measured cubes, and 3D printed archeological objects, for which we will allow an excess 1mm accuracy violation due to the inconsistencies of 3D printing.

Chakara’s Status Update for 2/15/2020

This week, I was working on two main parts, finalizing the project requirements with the team and researching on sensor capsule and platform. In finalizing the project requirements, I mainly worked on the Usability requirement as the other parts were mostly done together with other team members. At the beginning of the week, we decided we would potentially be using Intel real-sense depth camera (RGB-D camera using coded light) instead of other cameras and sensors for our sensor (though this may change now after getting feedback from Professor Mukherjee). First, we updated the Usability requirement where we specified our object dimensions to be from 5cm to 25cm along each axis. After getting sensor specifications and information from Jeremy, I computed the platform dimensions. The Intel real-sense depth camera S305 has Depth Field of View (Horizontal x Vertical) of 69 degrees +- 3 degrees and 54 degrees +- 2 degrees. From this information, I computed that the camera has to be around 26 cm away from the object side. The image below shows the basic calculation and our initial design of the platform.

Our initial design places the camera at the center of the largest object size possible, but this may have to be calibrated depending on the reconstruction technique we decide to use and the data we receive from the sensor. However, this would be done later once we have the basic implementation of the system done. 

Another metric we added to the Usability requirement is also the weight limit of the input object size. Since our use-case is to be able to model archaeological documentation, I used baked clay and potteries as our base. The average pottery pot thickness is around 0.6-0.9cm in which I rounded up to 1cm. With this, I computed the volume based on our maximum input object dimensions and used the density of baked clay to compute the average mass of the object, 6.91kg. We rounded this up and used 7kg as our input object weight limit. Since we would also be testing by printing out 3D object from models, I used the density of plastic to compute that our test objects would have mass under our weight limit in which they do (around 4.3kg).

After having the weight requirement and platform dimensions, I started researching on how to design a rotational mechanism. 

My progress is a little behind schedule. This is mainly because we still have not fully decided on the sensor type to use, so the platform design may have to change in the future. Our team would have to finalize our sensor by this Monday at the latest so that I would have time to design the platform and rotational mechanism. Moreover, I am also behind schedule because I underestimated the complexity of the rotational mechanism. I would have to do a lot more research and potentially ask for advice from someone with expertise in the area.

For next week, I hope to finish the draft design of the rotational mechanism and the platform. After doing some research, I now realize that I would have to take into account the object’s weight distribution to calculate moments and determine the ratio I need of the base to the platform to ensure stability. In addition, I would also need to compute how much torque I need on the motor to be able to order the right mechanical components. I would also need to design a feature extractor system that, based on the weight of the object, be able to control the rotational mechanism to give the sensor the rotation velocity it needs. I would also need to do more research on the material type of the platform itself. 

Alex’s Status Update for 2/15/2020

This week I spent time researching the common pipeline generally utilized in 3D Mesh reconstruction from raw depth data. The core of the pipeline is the Pairwise Registration stage, which aims to join localized point clouds from each perspective into a global 3D coordinate space. A common technique to accomplish this is the Iterative Closest Point (ICP) algorithm, which estimates the rotation between two subsequent views of depth information, and continuously iterates on this value until relative points line up with a low mean squared error cost. Once the rotations have been computed between relative views, rotational matrices can be applied to each view to transform them into a global coordinate space, thus achieving a final point cloud. It is possible for us to provide an initial estimate for the rotation by capturing data from our rotational mechanism, but we will still utilize an iterative approach, since this initial recording may not be accurate with the depth info collected.

Problems with ICP include: time complexity is quadratic in number of points, since each pair of points is considered (Oct-tree or similar data structure can get this to O(nlogn)); some points may not have corresponding points in the subsequent view; if two views are at far enough angles, the algorithm can be trapped in a local minimum. Many variants of the ICP algorithm exist, which select points from each view, match points between the views, weight pairs of points between the views, and define error metrics differently. These decisions are aimed to eliminate systematic biases in our system which may result in the algorithm being stuck in a local maximum. For example, if our sensor captured RGB data with each depth point, matching points can be biased with this information, likely resulting in an algorithm that will match correct points more often. We prioritize accuracy more than we do performance, based on our stated project requirements during our project proposal. Because of this, our choice in a variant of the ICP algorithm will be based on avoiding local minima which will skew the accuracy of our final point cloud. From this we are pushed to make our rotational mechanism rotate a small angle between views, and possibly make our sensor capture RGB data for ease of point matching.

Other steps which we will also need to consider are pre-filtering and point-cloud generation for each view. These steps are largely dependent on the sensor data we receive, and thus are dependent on the devices we choose to capture the data, which Jeremy has done research in this week. Finally, mesh construction from the point cloud and optional (stretch goal) texture mapping must be done to form a usable 3D format for the user. We must choose a format for the output mesh (volume-based or triangular surface mesh), and then choose a corresponding algorithm appropriately. Triangular surface meshes are more generally usable by more software, so if we choose a volumetric approach, we may utilize a public library to triangulate the result. It will be easier to directly implement the construction of a volumetric mesh from point-cloud data, so for the sake of time (and not re-inventing the wheel of triangulation algorithm implementations), we will most likely choose this approach.

Below is a general diagram of our initial algorithmic pipeline. Much of the details need to be sorted out based on our data collection mechanism. Our ability to provide texture mapping is also dependent on whether our sensor captures RGB data.

Algorithmic Pipeline Diagram

In terms of developing our algorithmic approach, we are on the schedule set by our Gantt chart. In the next week we will have chosen a specific sensor approach, which will enable us to narrow in on our pre-filtering and point-cloud generation techniques. By this point we will also be able to choose a variant of the ICP algorithm for pairwise registration based on foreseen metric trade-offs. Finally, with our sensor chosen, we can determine whether or not we will be able to perform texture mapping as a stretch goal. At the end of next week, after our algorithmic pipeline has been determined to a large degree, we can plan the specific technologies we will utilize to implement each stage.

As of now to manage risk, we are choosing techniques general enough that regardless of sources of error from the sensor side, we can accommodate by adding an additional filtering step during pre-processing. This is, of course, assuming the sensor data does not have egregiously high noise.