3 * dyncnn is a deep-learning algorithm for the prediction of
4 * interacting object dynamics
6 * Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/
7 * Written by Francois Fleuret <francois.fleuret@idiap.ch>
9 * This file is part of dyncnn.
11 * dyncnn is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 3 as
13 * published by the Free Software Foundation.
15 * dyncnn is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with dyncnn. If not, see <http://www.gnu.org/licenses/>.
39 #include "canvas_cairo.h"
41 void generate_png(Universe *universe, scalar_t scale, FILE *file) {
42 CanvasCairo canvas(scale, universe->width(), universe->height());
43 canvas.set_line_width(1.0 / scale);
44 universe->draw(&canvas);
45 canvas.write_png(file);
48 FILE *safe_fopen(const char *name, const char *mode) {
49 FILE *file = fopen(name, mode);
51 cerr << "Cannot open " << name << endl;
57 void print_help(const char *command) {
58 cerr << command << " <nb sequences to generate> [--dir <dir>] [--seed <seed>]]" << endl;
62 int main(int argc, char **argv) {
63 const scalar_t world_width = 400;
64 const scalar_t world_height = 400;
65 const scalar_t block_size = 80;
67 const scalar_t dt = 0.1;
68 const int nb_iterations_per_steps = 20;
70 //////////////////////////////////////////////////////////////////////
72 // We will generate images { 0, every_nth, 2 * every_nth, ..., nb_frames - 1 }
74 // The framerate every_nth may be set to smaller value to generate
75 // nice materials for presentations or papers.
83 char data_dir[1024] = "/tmp/";
85 //////////////////////////////////////////////////////////////////////
88 Polygon *grabbed_polygon;
94 int nb_sequences = atoi(argv[1]);
98 if(strcmp(argv[i], "--dir") == 0) {
100 if(i == argc) { print_help(argv[0]);}
101 strncpy(data_dir, argv[i], sizeof(data_dir) / sizeof(char) - 1);
105 else if(strcmp(argv[i], "--seed") == 0) {
107 if(i == argc) { print_help(argv[0]); }
108 srand48(atoi(argv[i]));
112 else if(strcmp(argv[i], "--nb_shapes") == 0) {
114 if(i == argc) { print_help(argv[0]);}
115 nb_shapes = atoi(argv[i]);
119 else if(strcmp(argv[i], "--multi_grasp") == 0) {
124 else if(strcmp(argv[i], "--every_nth") == 0) {
126 if(i == argc) { print_help(argv[0]);}
127 every_nth = atoi(argv[i]);
131 else if(strcmp(argv[i], "--nb_frames") == 0) {
133 if(i == argc) { print_help(argv[0]);}
134 nb_frames = atoi(argv[i]);
139 cerr << "Unknown option " << argv[i] << "." << endl;
144 if(nb_shapes < 1 || nb_shapes > 10) {
145 cerr << "nb_shapes has to be in {1, ..., 10}" << endl;
149 if(nb_frames < 0 || nb_frames > 50) {
150 cerr << "nb_frames has to be in {0, ..., 50}" << endl;
154 universe = new Universe(nb_shapes, world_width, world_height);
156 for(int n = 0; n < nb_sequences; n++) {
158 scalar_t grab_start_x = world_width * 0.5;
159 scalar_t grab_start_y = world_height * 0.75;
162 grab_start_x = world_width * (0.1 + 0.8 * drand48());
163 grab_start_y = world_height * (0.1 + 0.8 * drand48());
168 << n+1 << "/" << nb_sequences << " sequences in "
176 const int nb_attempts_max = 100;
179 for(int u = 0; u < nb_shapes; u++) {
199 scalar_t delta = block_size / sqrt(2.0);
200 scalar_t object_center_x = delta + (world_width - 2 * delta) * drand48();
201 scalar_t object_center_y = delta + (world_height - 2 * delta) * drand48();
202 scalar_t red, green, blue;
207 pol = new Polygon(0.5,
209 x, y, sizeof(x)/sizeof(scalar_t));
210 pol->set_position(object_center_x, object_center_y, M_PI * 2 * drand48());
211 pol->set_speed(0, 0, 0);
212 universe->initialize_polygon(pol);
214 } while(nb_attempts < nb_attempts_max && universe->collide(pol));
216 if(nb_attempts == nb_attempts_max) {
222 universe->add_polygon(pol);
226 grabbed_polygon = universe->pick_polygon(grab_start_x, grab_start_y);
227 } while(!grabbed_polygon);
229 const scalar_t scaling = 0.16;
231 CanvasCairo grab_trace(scaling, world_width, world_height);
235 sprintf(buffer, "%s/%03d/", data_dir, n/1000);
239 scalar_t grab_relative_x = grabbed_polygon->relative_x(grab_start_x, grab_start_y);
240 scalar_t grab_relative_y = grabbed_polygon->relative_y(grab_start_x, grab_start_y);
244 scalar_t xp[n], yp[n];
245 for(int k = 0; k < n; k++) {
246 scalar_t radius = 1/scaling;
247 scalar_t alpha = 2 * M_PI * scalar_t(k) / scalar_t(n);
248 xp[k] = grab_start_x + radius * cos(alpha);
249 yp[k] = grab_start_y + radius * sin(alpha);
251 grab_trace.set_drawing_color(0.0, 0.0, 0.0);
252 grab_trace.set_line_width(2.0);
253 grab_trace.draw_polygon(1, n, xp, yp);
256 for(int s = 0; s < nb_frames; s++) {
257 if(s % every_nth == 0) {
259 sprintf(buffer, "%s/%03d/dyn_%06d_world_%03d.png", data_dir, n/1000, n, s);
260 FILE *file = safe_fopen(buffer, "w");
261 generate_png(universe, scaling, file);
265 for(int i = 0; i < nb_iterations_per_steps; i++) {
266 scalar_t xf = grabbed_polygon->absolute_x(grab_relative_x, grab_relative_y);
267 scalar_t yf = grabbed_polygon->absolute_y(grab_relative_x, grab_relative_y);
268 grabbed_polygon->apply_force(dt, xf, yf, 0.0, -1.0);
269 universe->update(dt);
275 sprintf(buffer, "%s/%03d/dyn_%06d_grab.png", data_dir, n/1000, n);
276 FILE *file = safe_fopen(buffer, "w");
277 grab_trace.write_png(file);