NetDEM v1.0
Loading...
Searching...
No Matches
36_test_ann_vs_geom_ellipsoid.cpp

This is an example of how to use the netdem library.

#include "general_net.hpp"
#include "igl_wrapper.hpp"
#include "mlpack_utils.hpp"
#include "particle.hpp"
#include "shape_plane.hpp"
#include "utils_math.hpp"
#include <fstream>
#include <iostream>
#include <random>
#include <sstream>
#include <string>
using namespace netdem;
using namespace std;
void TestANNvsGeometricEllipsoid() {
// load particle
Ellipsoid ellipsoid = Ellipsoid(1, 1, 2);
ellipsoid.SetSize(1.0);
Particle obj_p1 = Particle(&ellipsoid);
Particle obj_p2 = Particle(&ellipsoid);
cout << "particle created ... " << endl;
SolverGJKPP cnt_solver;
LinearSpring cnt_model;
string root_dir = "local/examples/netdem/ann_models/ellipsoid_ellipsoid/";
GeneralNet classifier;
classifier.Load(root_dir + "ann_classifier.xml", "detection");
RegressionNet regressor;
regressor.Load(root_dir + "ann_regressor.xml", "resolution");
double dist_max = obj_p2.shape->GetBoundSphereRadius() * 2;
double dist_min = dist_max / 2 * 0.9;
double dist_range = dist_max - dist_min;
// random generator
UniformDistribution uniform_dist(0.0, 1.0);
// use spherical centroidal voronoi to sample uniform unit VecXT
VecXT<Vec3d> vertices = SphericalVoronoi::Solve(1000, 10000, 1.0e-4);
VecXT<Vec3i> facets;
IGLWrapper::ConvexHull(vertices, &vertices, &facets);
// random cases
for (int trial = 0; trial < 100; trial++) {
// random rotation
Vec4d quat;
quat[0] = uniform_dist.Get() * 2.0 - 1.0;
quat[1] = uniform_dist.Get() * 2.0 - 1.0;
quat[2] = uniform_dist.Get() * 2.0 - 1.0;
quat[3] = uniform_dist.Get() * 2.0 - 1.0;
Math::Quaternion::Normalize(&quat);
// random position
int id_facet = floor(uniform_dist.Get() * facets.size());
auto vert_0 = vertices[facets[id_facet][0]];
auto vert_1 = vertices[facets[id_facet][1]];
auto vert_2 = vertices[facets[id_facet][2]];
double u_vert = uniform_dist.Get();
double v_vert = uniform_dist.Get() * (1 - u_vert);
double w_vert = 1 - u_vert - v_vert;
Vec3d pos;
pos[0] = u_vert * vert_0[0] + v_vert * vert_1[0] + w_vert * vert_2[0];
pos[1] = u_vert * vert_0[1] + v_vert * vert_1[1] + w_vert * vert_2[1];
pos[2] = u_vert * vert_0[2] + v_vert * vert_1[2] + w_vert * vert_2[2];
Math::Normalize(&pos);
auto dist_pp = dist_min + uniform_dist.Get() * dist_range;
pos[0] *= dist_pp;
pos[1] *= dist_pp;
pos[2] *= dist_pp;
// apply to particle
obj_p2.SetPosition(pos[0], pos[1], pos[2]);
obj_p2.SetQuaternion(quat[0], quat[1], quat[2], quat[3]);
// contact detection and resolution
arma::mat input(7, 1, arma::fill::zeros);
input(0, 0) = obj_p2.pos[0];
input(1, 0) = obj_p2.pos[1];
input(2, 0) = obj_p2.pos[2];
input(3, 0) = obj_p2.quaternion[0] * Math::Sign(obj_p2.quaternion[0]);
input(4, 0) = obj_p2.quaternion[1] * Math::Sign(obj_p2.quaternion[0]);
input(5, 0) = obj_p2.quaternion[2] * Math::Sign(obj_p2.quaternion[0]);
input(6, 0) = obj_p2.quaternion[3] * Math::Sign(obj_p2.quaternion[0]);
auto output = classifier.Classify(input);
cnt_solver.Init(&obj_p1, &obj_p2);
auto cnt_flag_geo = cnt_solver.Detect();
cout << "ann vs geometric: " << output(0) << ", " << cnt_flag_geo << endl;
if (cnt_flag_geo) {
auto cnt = ContactPP(&obj_p1, &obj_p2);
cnt.SetCollisionModel(&cnt_model);
cnt_solver.ResolveInit(&cnt, 1.0e-4);
auto &cnt_geoms = cnt.collision_entries[0].cnt_geoms;
// skip the contact if overlap is too large
if (cnt_geoms.len_n > 0.05)
continue;
auto output = regressor.Predict(input);
cout << ">> ann: " << output(0, 0) / 40.0 << ", " << output(1, 0) << ", "
<< output(2, 0) << ", " << output(3, 0) << ", " << output(4, 0)
<< ", " << output(5, 0) << ", " << output(6, 0) << endl;
cout << ">> geo: " << cnt_geoms.len_n << ", " << cnt_geoms.dir_n[0]
<< ", " << cnt_geoms.dir_n[1] << ", " << cnt_geoms.dir_n[2] << ", "
<< cnt_geoms.pos[0] << ", " << cnt_geoms.pos[1] << ", "
<< cnt_geoms.pos[2] << endl;
}
}
}
A class representing a contact between two particles.
Definition contact_pp.hpp:20
A class for representing an ellipsoid shape.
Definition shape_ellipsoid.hpp:15
void SetSize(double d) override
Set the size of the Ellipsoid object.
Definition shape_ellipsoid.cpp:51
A class representing a general neural network.
Definition general_net.hpp:19
void Load(std::string const &filename, std::string const &label)
Loads a previously saved neural network model from a file.
Definition general_net.cpp:74
arma::mat Classify(const arma::mat &data_x)
Classifies input data based on the current neural network model.
Definition general_net.cpp:65
Contact model that uses linear spring elements to evaluate contact forces and moments.
Definition model_linear_spring.hpp:16
Definition particle.hpp:26
virtual void SetQuaternion(double q_0, double q_1, double q_2, double q_3)
Sets the orientation of the particle using a quaternion.
Definition particle.cpp:103
virtual void SetPosition(double pos_x, double pos_y, double pos_z)
Sets the position of the particle.
Definition particle.cpp:83
Vec4d quaternion
The quaternion of the particle.
Definition particle.hpp:108
Vec3d pos
The position of the particle.
Definition particle.hpp:103
Shape * shape
The shape of the particle.
Definition particle.hpp:45
A class that represents a feedforward neural network for regression.
Definition regression_net.hpp:21
void Load(std::string const &filename, std::string const &label)
Loads the neural network model from disk.
Definition regression_net.cpp:95
arma::mat Predict(const arma::mat &data_x)
Predicts with the neural network model using input data.
Definition regression_net.cpp:62
virtual double GetBoundSphereRadius() const
Return the inertia of the shape.
Definition shape.cpp:126
GJK solver for convex geometries.
Definition solver_gjk_pp.hpp:15
bool Detect() override
Detects collisions between the two particles.
Definition solver_gjk_pp.cpp:40
void Init(Particle *const p1, Particle *const p2) override
Initializes the collision solver with two particles.
Definition solver_gjk_pp.cpp:22
void ResolveInit(ContactPP *const cnt, double timestep) override
Initializes the contact point between two particles at time t = 0.
Definition solver_gjk_pp.cpp:64
Generates random numbers from a uniform distribution.
Definition distribution_uniform.hpp:15
double Get() override
Get a single random number from the uniform distribution.
Definition distribution_uniform.hpp:58
Definition bond_entry.hpp:7
std::vector< T > VecXT
Definition utils_macros.hpp:31
std::array< double, 3 > Vec3d
Definition utils_macros.hpp:18
std::array< double, 4 > Vec4d
Definition utils_macros.hpp:19