Commit 3dd9d235 authored by François Heremans's avatar François Heremans
Browse files

Added MBSysC websocket module

parent c8483a4b
...@@ -6,12 +6,14 @@ ...@@ -6,12 +6,14 @@
* In order to use C++ features, you just need to change the extension of this file (.c) to .cc (or .cpp). * In order to use C++ features, you just need to change the extension of this file (.c) to .cc (or .cpp).
*/ */
#ifdef SDL
#include "realtime.h" #include "realtime.h"
#include "events_sdl.h" #include "events_sdl.h"
#include "user_realtime.h" #include "user_realtime.h"
#ifdef SDL
/*! \brief handle inputs comming from the keyboard /*! \brief handle inputs comming from the keyboard
* *
* \param[in,out] mbs_data Robotran main structure * \param[in,out] mbs_data Robotran main structure
...@@ -92,3 +94,9 @@ void user_joystick_buttons(MbsData* mbs_data, int buttonID) ...@@ -92,3 +94,9 @@ void user_joystick_buttons(MbsData* mbs_data, int buttonID)
} }
#endif #endif
#ifdef WEBSOCKET
void user_keyboard(MbsData* mbs_data, Simu_realtime *realtime, int keyevent, int state){
}
#endif
\ No newline at end of file
...@@ -193,7 +193,7 @@ int main(int argc, char const *argv[]) ...@@ -193,7 +193,7 @@ int main(int argc, char const *argv[])
mbs_dirdyn->options->dt0 = 1e-3; mbs_dirdyn->options->dt0 = 1e-3;
mbs_dirdyn->options->tf = 10.0; mbs_dirdyn->options->tf = 10.0;
mbs_dirdyn->options->save2file = 1; mbs_dirdyn->options->save2file = 1;
//mbs_dirdyn->options->realtime = 1; mbs_dirdyn->options->realtime = 1;
mbs_run_dirdyn(mbs_dirdyn, mbs_data); mbs_run_dirdyn(mbs_dirdyn, mbs_data);
......
...@@ -75,6 +75,9 @@ function(mbsysc_specific_flags) # flag for lib_mbsysC only (not set by project) ...@@ -75,6 +75,9 @@ function(mbsysc_specific_flags) # flag for lib_mbsysC only (not set by project)
# enable frame capture to record screenshot of the simulation # enable frame capture to record screenshot of the simulation
cmake_dependent_option(FLAG_FRAME_CAPTURE "Enable frame capture (need OpenGL)" OFF "FLAG_OPEN_GL" OFF) cmake_dependent_option(FLAG_FRAME_CAPTURE "Enable frame capture (need OpenGL)" OFF "FLAG_OPEN_GL" OFF)
# use the websocket to display in real-time the animation
cmake_dependent_option(FLAG_WEBSOCKET "Enable web 3D visualization" ON "FLAG_VISU" OFF)
endfunction() endfunction()
## -- Static, dynamic libraries -- ## ## -- Static, dynamic libraries -- ##
...@@ -106,12 +109,14 @@ function(flags_check) ...@@ -106,12 +109,14 @@ function(flags_check)
set( FLAG_VISU OFF ) set( FLAG_VISU OFF )
set( FLAG_JAVA OFF ) set( FLAG_JAVA OFF )
set( FLAG_OPEN_GL OFF ) set( FLAG_OPEN_GL OFF )
set( FLAG_WEBSOCKET OFF )
endif( ) endif( )
# 3D visu # 3D visu
if (NOT FLAG_VISU) if (NOT FLAG_VISU)
set( FLAG_JAVA OFF ) set( FLAG_JAVA OFF )
set( FLAG_OPEN_GL OFF ) set( FLAG_OPEN_GL OFF )
set( FLAG_WEBSOCKET OFF )
endif( ) endif( )
# OpenGL only if no Java # OpenGL only if no Java
...@@ -165,6 +170,7 @@ function(flags_check) ...@@ -165,6 +170,7 @@ function(flags_check)
set( FLAG_VISU ${FLAG_VISU} PARENT_SCOPE ) set( FLAG_VISU ${FLAG_VISU} PARENT_SCOPE )
set( FLAG_JAVA ${FLAG_JAVA} PARENT_SCOPE ) set( FLAG_JAVA ${FLAG_JAVA} PARENT_SCOPE )
set( FLAG_OPEN_GL ${FLAG_OPEN_GL} PARENT_SCOPE ) set( FLAG_OPEN_GL ${FLAG_OPEN_GL} PARENT_SCOPE )
set( FLAG_WEBSOCKET ${FLAG_WEBSOCKET} PARENT_SCOPE )
set( FLAG_SHARED_LIB ${FLAG_SHARED_LIB} PARENT_SCOPE ) set( FLAG_SHARED_LIB ${FLAG_SHARED_LIB} PARENT_SCOPE )
set( FLAG_SEPARATE_BUILD ${FLAG_SEPARATE_BUILD} PARENT_SCOPE ) set( FLAG_SEPARATE_BUILD ${FLAG_SEPARATE_BUILD} PARENT_SCOPE )
set( FLAG_SEPARATE_SYMBOLIC ${FLAG_SEPARATE_SYMBOLIC} PARENT_SCOPE ) set( FLAG_SEPARATE_SYMBOLIC ${FLAG_SEPARATE_SYMBOLIC} PARENT_SCOPE )
...@@ -195,6 +201,7 @@ function(flags_clean) ...@@ -195,6 +201,7 @@ function(flags_clean)
unset(FLAG_VISU CACHE) unset(FLAG_VISU CACHE)
unset(FLAG_JAVA CACHE) unset(FLAG_JAVA CACHE)
unset(FLAG_OPEN_GL CACHE) unset(FLAG_OPEN_GL CACHE)
unset(FLAG_WEBSOCKET CACHE)
unset(JNI_INCLUDE_JNI CACHE) unset(JNI_INCLUDE_JNI CACHE)
unset(JNI_INCLUDE_JNI_MD CACHE) unset(JNI_INCLUDE_JNI_MD CACHE)
unset(SDL2_LIBRARIES_SDL2 CACHE) unset(SDL2_LIBRARIES_SDL2 CACHE)
...@@ -267,5 +274,9 @@ function(definitions) ...@@ -267,5 +274,9 @@ function(definitions)
set(LIB_MBSYSC_DEFINITIONS ${LIB_MBSYSC_DEFINITIONS} -DFRAME_CAPTURE) set(LIB_MBSYSC_DEFINITIONS ${LIB_MBSYSC_DEFINITIONS} -DFRAME_CAPTURE)
endif( ) endif( )
if(FLAG_WEBSOCKET)
add_definitions( -DWEBSOCKET )
endif( )
set(LIB_MBSYSC_DEFINITIONS ${LIB_MBSYSC_DEFINITIONS} PARENT_SCOPE) set(LIB_MBSYSC_DEFINITIONS ${LIB_MBSYSC_DEFINITIONS} PARENT_SCOPE)
endfunction() endfunction()
...@@ -133,6 +133,14 @@ if (FLAG_REAL_TIME AND FLAG_OPEN_GL) ...@@ -133,6 +133,14 @@ if (FLAG_REAL_TIME AND FLAG_OPEN_GL)
include_directories ("${PROJECT_BINARY_DIR}/conf") include_directories ("${PROJECT_BINARY_DIR}/conf")
endif () endif ()
# Websocket files
if (FLAG_WEBSOCKET)
include_directories("./websocket")
increment_src( ${PROJECT_SOURCE_DIR}/websocket )
add_definitions( -DWEBSOCKET )
include_directories ("${PROJECT_BINARY_DIR}/conf")
endif ()
# list include directories (to find headers) # list include directories (to find headers)
init_include() init_include()
set(INCLUDE_DIR ${INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/realtime PARENT_SCOPE) set(INCLUDE_DIR ${INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/realtime PARENT_SCOPE)
...@@ -178,8 +186,8 @@ set(LIB_MBSYSC_REALTIME_PATH ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) ...@@ -178,8 +186,8 @@ set(LIB_MBSYSC_REALTIME_PATH ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
# include directories # include directories
include_directories("./") include_directories("./")
include_directories("./sdl" "./sdl/auto_plot") include_directories("./sdl")
include_directories("./realtime") include_directories("./realtime" "./realtime/auto_plot")
include_directories("../mbs_struct") include_directories("../mbs_struct")
include_directories("../mbs_utilities") include_directories("../mbs_utilities")
include_directories("../mbs_numerics") include_directories("../mbs_numerics")
......
#ifdef SDL
#include "auto_plot.h" #include "auto_plot.h"
#include "useful_functions.h" #include "useful_functions.h"
...@@ -106,4 +105,4 @@ int index_plot_string(AutoPlot *auto_plot, const char* label) ...@@ -106,4 +105,4 @@ int index_plot_string(AutoPlot *auto_plot, const char* label)
return -1; return -1;
} }
#endif
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
* \brief functions used to automatically update the user curves plotted * \brief functions used to automatically update the user curves plotted
*/ */
#ifdef SDL
#ifndef _AUTO_PLOT_H_ #ifndef _AUTO_PLOT_H_
#define _AUTO_PLOT_H_ #define _AUTO_PLOT_H_
...@@ -30,5 +29,5 @@ void free_auto_plot(AutoPlot *auto_plot); ...@@ -30,5 +29,5 @@ void free_auto_plot(AutoPlot *auto_plot);
void update_auto_plot(AutoPlot *auto_plot, double value, const char* label); void update_auto_plot(AutoPlot *auto_plot, double value, const char* label);
int index_plot_string(AutoPlot *auto_plot, const char* label); int index_plot_string(AutoPlot *auto_plot, const char* label);
#endif
#endif #endif
...@@ -3,10 +3,6 @@ ...@@ -3,10 +3,6 @@
#endif // !HAVE_M_PI #endif // !HAVE_M_PI
#include "set_plot.h" #include "set_plot.h"
#ifdef SDL
#include "auto_plot.h" #include "auto_plot.h"
static AutoPlot *auto_plot; // static AutoPlot structure with all the current user plots information static AutoPlot *auto_plot; // static AutoPlot structure with all the current user plots information
...@@ -21,10 +17,13 @@ void reset_flag_plot() ...@@ -21,10 +17,13 @@ void reset_flag_plot()
flag_plot = 0; flag_plot = 0;
} }
/*! \brief initialize the static auto_plot structure /*! \brief initialize the static auto_plot structure
* *
* \param[in,out] screen_sdl SDL gestion main structure * \param[in,out] screen_sdl SDL gestion main structure
*/ */
#ifdef SDL
void init_set_plot(Screen_sdl *screen_sdl) void init_set_plot(Screen_sdl *screen_sdl)
{ {
flag_plot = 1; flag_plot = 1;
...@@ -33,6 +32,17 @@ void init_set_plot(Screen_sdl *screen_sdl) ...@@ -33,6 +32,17 @@ void init_set_plot(Screen_sdl *screen_sdl)
screen_sdl->auto_plot = auto_plot; screen_sdl->auto_plot = auto_plot;
} }
#else
void init_set_plot(Realtime_extern *realtime_ext, int max_nb_curves)
{
flag_plot = 1;
auto_plot = init_auto_plot(max_nb_curves);
realtime_ext->auto_plot = auto_plot;
}
#endif
/*! \brief release memory of auto_plot /*! \brief release memory of auto_plot
*/ */
...@@ -56,5 +66,3 @@ void set_plot(double value, char* label) ...@@ -56,5 +66,3 @@ void set_plot(double value, char* label)
update_auto_plot(auto_plot, value, label); update_auto_plot(auto_plot, value, label);
} }
} }
#endif
...@@ -11,9 +11,12 @@ ...@@ -11,9 +11,12 @@
#include "plot_sdl.h" #include "plot_sdl.h"
#ifdef SDL #ifdef SDL
void reset_flag_plot();
void init_set_plot(Screen_sdl *screen_sdl); void init_set_plot(Screen_sdl *screen_sdl);
void free_set_plot(); #else
void init_set_plot(Realtime_extern *realtime_ext, int max_nb_curves);
#endif #endif
void reset_flag_plot();
void free_set_plot();
#endif #endif
...@@ -29,6 +29,11 @@ ...@@ -29,6 +29,11 @@
#include "open_gl_c_int.h" #include "open_gl_c_int.h"
#endif #endif
#ifdef WEBSOCKET
#include "visu_websocket.h"
#include "auto_plot/set_plot.h"
#endif
// -- Macros -- // // -- Macros -- //
#define USEC_TO_SEC 1.0e-6 //!< factor from us to s #define USEC_TO_SEC 1.0e-6 //!< factor from us to s
...@@ -127,6 +132,13 @@ void mbs_realtime_update(Simu_realtime *realtime, double tsim) ...@@ -127,6 +132,13 @@ void mbs_realtime_update(Simu_realtime *realtime, double tsim)
update_past_visu(realtime, tsim); update_past_visu(realtime, tsim);
} }
#endif #endif
#ifdef WEBSOCKET
if (realtime->flag_plot)
{
update_plot_vectors(realtime, tsim);
}
#endif
} }
/*! \brief one loop iteration of the real-time process /*! \brief one loop iteration of the real-time process
...@@ -223,6 +235,8 @@ int mbs_realtime_loop(Simu_realtime *realtime, double tsim) ...@@ -223,6 +235,8 @@ int mbs_realtime_loop(Simu_realtime *realtime, double tsim)
mbs_msg("\t >Real-time> Error: update open GL ! \n"); mbs_msg("\t >Real-time> Error: update open GL ! \n");
return err; return err;
} }
#elif (defined WEBSOCKET)
update_websocket(realtime);
#endif #endif
} }
} }
...@@ -657,6 +671,11 @@ Simu_realtime* init_simu_realtime(MbsData* mbs_data, Realtime_option *options, i ...@@ -657,6 +671,11 @@ Simu_realtime* init_simu_realtime(MbsData* mbs_data, Realtime_option *options, i
return NULL; return NULL;
} }
} }
#elif WEBSOCKET
{
init_set_plot(realtime->ext, 10);
// printf("\n Plot activated to websocket !\n");
}
#else #else
if (options->flag_plot) if (options->flag_plot)
{ {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "realtime_ext.h" #include "realtime_ext.h"
#include "color_sdl.h" #include "color_sdl.h"
#include "mbs_data.h" #include "mbs_data.h"
#include "auto_plot/auto_plot.h"
#include "mbs_project_fct_ptr.h" #include "mbs_project_fct_ptr.h"
...@@ -33,6 +34,8 @@ typedef struct Realtime_extern ...@@ -33,6 +34,8 @@ typedef struct Realtime_extern
Realtime_visu *visu; //!< Java structure Realtime_visu *visu; //!< Java structure
#endif #endif
AutoPlot *auto_plot; ///< automatic user plot update structure
MbsData* mbs_data; //!< Robotran main structure MbsData* mbs_data; //!< Robotran main structure
} Realtime_extern; } Realtime_extern;
...@@ -77,6 +80,7 @@ struct Realtime_option ...@@ -77,6 +80,7 @@ struct Realtime_option
int nb_models; //!< number of models to load int nb_models; //!< number of models to load
int *nb_q; //!< number of joints in the .mbs used for visualization (for each model) int *nb_q; //!< number of joints in the .mbs used for visualization (for each model)
char **mbs_file; //!< path and file name fot the .mbs file used for Java visualization (for each model) char **mbs_file; //!< path and file name fot the .mbs file used for Java visualization (for each model)
char *project_path; //!< path for the project
int start_viewpoint; //!< initial visu viewpoint ID int start_viewpoint; //!< initial visu viewpoint ID
......
...@@ -27,6 +27,10 @@ ...@@ -27,6 +27,10 @@
#include "open_gl_c_int.h" #include "open_gl_c_int.h"
#endif #endif
#ifdef WEBSOCKET
#include "visu_websocket.h"
#endif
#ifdef SDL #ifdef SDL
/*! \brief initialize SDL real-time variables /*! \brief initialize SDL real-time variables
...@@ -211,6 +215,8 @@ Realtime_visu* init_realtime_visu(void *realtime_options, MbsData* mbs_data, int ...@@ -211,6 +215,8 @@ Realtime_visu* init_realtime_visu(void *realtime_options, MbsData* mbs_data, int
mbs_msg("\t >Real-time> Error [%d] :in init_open gl visu ! \n", *err); mbs_msg("\t >Real-time> Error [%d] :in init_open gl visu ! \n", *err);
return NULL; return NULL;
} }
#elif (defined WEBSOCKET)
init_websocket(visu, mbs_data, nb_models, nb_q, visu->cur_q, options->mbs_file, options->project_path, options->start_viewpoint);
#endif #endif
*err = 0; *err = 0;
return visu; return visu;
...@@ -259,8 +265,9 @@ int free_realtime_visu(Realtime_visu *visu) ...@@ -259,8 +265,9 @@ int free_realtime_visu(Realtime_visu *visu)
mbs_msg("\t >Real-time> Error: free open GL ! \n"); mbs_msg("\t >Real-time> Error: free open GL ! \n");
return err; return err;
} }
#elif (defined WEBSOCKET)
free_websocket(visu->visu_class);
#endif #endif
free(visu); free(visu);
return 0; return 0;
} }
......
...@@ -25,6 +25,18 @@ extern "C" { ...@@ -25,6 +25,18 @@ extern "C" {
#endif #endif
#endif #endif
#ifdef WEBSOCKET
#ifdef __cplusplus
extern "C" {
#endif
void user_realtime_plot(MbsData* mbs_data);
void user_keyboard(MbsData* mbs_data, Simu_realtime *realtime, int keyevent, int state);
#ifdef __cplusplus
}
#endif
#endif
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
......
This diff is collapsed.
/*
Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com)
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef CCAN_JSON_H
#define CCAN_JSON_H
#include <stdbool.h>
#include <stddef.h>
typedef enum {
JSON_NULL,
JSON_BOOL,
JSON_STRING,
JSON_NUMBER,
JSON_ARRAY,
JSON_OBJECT,
} JsonTag;
typedef struct JsonNode JsonNode;
struct JsonNode
{
/* only if parent is an object or array (NULL otherwise) */
JsonNode *parent;
JsonNode *prev, *next;
/* only if parent is an object (NULL otherwise) */
char *key; /* Must be valid UTF-8. */
JsonTag tag;
union {
/* JSON_BOOL */
bool bool_;
/* JSON_STRING */
char *string_; /* Must be valid UTF-8. */
/* JSON_NUMBER */
double number_;
/* JSON_ARRAY */
/* JSON_OBJECT */
struct {
JsonNode *head, *tail;
} children;
};
};
/*** Encoding, decoding, and validation ***/
JsonNode *json_decode (const char *json);
char *json_encode (const JsonNode *node);
char *json_encode_string (const char *str);
char *json_stringify (const JsonNode *node, const char *space);
void json_delete (JsonNode *node);
bool json_validate (const char *json);
/*** Lookup and traversal ***/
JsonNode *json_find_element (JsonNode *array, int index);
JsonNode *json_find_member (JsonNode *object, const char *key);
JsonNode *json_first_child (const JsonNode *node);
#define json_foreach(i, object_or_array) \
for ((i) = json_first_child(object_or_array); \
(i) != NULL; \
(i) = (i)->next)
/*** Construction and manipulation ***/
JsonNode *json_mknull(void);
JsonNode *json_mkbool(bool b);
JsonNode *json_mkstring(const char *s);
JsonNode *json_mknumber(double n);
JsonNode *json_mkarray(void);
JsonNode *json_mkobject(void);
void json_append_element(JsonNode *array, JsonNode *element);
void json_prepend_element(JsonNode *array, JsonNode *element);
void json_append_member(JsonNode *object, const char *key, JsonNode *value);
void json_prepend_member(JsonNode *object, const char *key, JsonNode *value);
void json_remove_from_parent(JsonNode *node);
/*** Debugging ***/
/*
* Look for structure and encoding problems in a JsonNode or its descendents.
*
* If a problem is detected, return false, writing a description of the problem
* to errmsg (unless errmsg is NULL).
*/
bool json_check(const JsonNode *node, char errmsg[256]);
#endif
#ifdef WEBSOCKET
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <string>
#include <sstream>
#include <chrono>
#include <thread>
#include <sys/time.h>
#include <ctime>
#include "visu_websocket.h"
#include "json.h"
#include <fcntl.h>
#include <poll.h>
int sock = 0;
char buffer[1024] = {0};
bool is_connected = false;
struct pollfd pfds[1]; // More if you want to monitor more
bool pause_sim = false;