raisimtech / raisimogre Goto Github PK
View Code? Open in Web Editor NEWLicense: Other
License: Other
Currently, raisimOgre moves under raisimTech group which uses LOCAL_INSTALL as a new directory name in raisimLib.
So, LOCAL_BUILD paramete names also should be changed to LOCAL_INSTALL
Hello,
I am trying to get a codebase working. This codebase works perfectly on another PC. On the current PC, the cmake works perfectly, but the executable throws this error. An another codebase works perfectly on this PC, meaning there should be no issue with the OGRE/raisimOgre install.
[2024:05:11:22:14:10 OgreVis.hpp:351] Loading RaisimOgre Resources from: [2024:05:11:22:14:10 OgreVis.hpp:352] Loading OGRE Configurations from: /home/ruturajsambhus/Work/raisim_legged/raisim_build/share/raisimOgre/cmake/../ogre/ terminate called after throwing an instance of 'Ogre::FileNotFoundException' what(): FileNotFoundException: Cannot locate resource collection.material in resource group General. in ResourceGroupManager::openResource at /home/ruturajsambhus/Work/raisim_legged/raisim_workspace/ogre/OgreMain/src/OgreResourceGroupManager.cpp (line 703) Aborted
It would be great if you could help me sort this out.
There is a typo in ogre cmake line:
What it is right now:
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$LOCAL_INSTALL -DOGRE_BUILD_COMPONENT_BITES=ON -DOGRE_BUILD_DEPENDENCIES=OFF -DOGRE_BUILD_SAMPLES=False OGRE_BUILD_COMPONENT_JAVA=OFF
Particularly, '-D' flag is missing in front of OGRE_BUILD_COMPONENT_JAVA=OFF
.
I was making a new URDF model and started debugging it with a simple application. However, the renderer just shows a black screen with my model. Though it seems to flash a single regular frame.
The command line shows no errors. I tried stepping through the code, that also provided no extra information.
The URDF model:
<?xml version="1.0"?>
<!-- Single tetrahedron (three-point pyramid), with four end-effectors on all corners -->
<robot name="tetrahedron">
<!-- Basic colors -->
<material name="gray">
<color rgba="0.2 0.2 0.2 1.0"/>
</material>
<link name="base_link">
<inertial>
<origin rpy="0 0 0" xyz="0 0 0"/>
<mass value="1.0"/>
<!-- Inertia of a sphere -->
<inertia ixx="0.4" ixy="0.0" ixz="0.0" iyy="0.4" iyz="0.0" izz="0.4"/>
</inertial>
<visual>
<origin rpy="0.0 0.0 0.0" xyz="0.0 0.0 0.0"/>
<geometry>
<sphere radius="0.5"/>
</geometry>
<material name="gray"/>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0.0 0.0 0.0"/>
<geometry>
<sphere radius="0.5"/>
</geometry>
</collision>
</link>
<!-- Corner 1 -->
<joint name="corner1_joint" type="fixed">
<parent link="bae_link"/>
<child link="corner1_link"/>
<origin rpy="0 0 0" xyz="0 0 0"/>
</joint>
<link name="corner1_link">
<visual>
<origin rpy="0.0 0.0 0.0" xyz="0.0 0.0 0.0"/>
<geometry>
<sphere radius="0.1"/>
</geometry>
<material name="gray"/>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0.0 0.0 0.0"/>
<geometry>
<sphere radius="0.1"/>
</geometry>
</collision>
</link>
</robot>
And the application with which I run the model (nearly identical to one of the provided examples):
/**
* This is a basic application that simulates a URDF file passed from the command line.
*/
#include <iostream>
#include <string>
#include <raisim/OgreVis.hpp>
#include "raisimBasicImguiPanel.hpp"
#include "raisimKeyboardCallback.hpp"
#include "helper.hpp"
void setupCallback() {
auto vis = raisim::OgreVis::get();
/// light
vis->getLight()->setDiffuseColour(1, 1, 1);
vis->getLight()->setCastShadows(true);
vis->getLightNode()->setPosition(3, 3, 3);
/// load textures
vis->addResourceDirectory(vis->getResourceDir() + "/material/gravel");
vis->loadMaterialFile("gravel.material");
vis->addResourceDirectory(vis->getResourceDir() + "/material/checkerboard");
vis->loadMaterialFile("checkerboard.material");
/// shadow setting
vis->getSceneManager()->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_ADDITIVE);
vis->getSceneManager()->setShadowTextureSettings(2048, 3);
/// scale related settings!! Please adapt it depending on your map size
// beyond this distance, shadow disappears
vis->getSceneManager()->setShadowFarDistance(60);
// size of contact points and contact forces
vis->setContactVisObjectSize(0.1, 3.0);
// speed of camera motion in freelook mode
vis->getCameraMan()->setTopSpeed(10);
/// background
Ogre::Quaternion quat;
quat.FromAngleAxis(Ogre::Radian(M_PI_2), {1., 0, 0});
vis->getSceneManager()->setSkyBox(true,
"white",
500,
true,
quat,
Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
}
int main(int argc, char **argv) {
//auto binaryPath = raisim::Path::setFromArgv(argv[0]);
//raisim::World::setActivationKey(binaryPath.getDirectory() + "/rsc/activation.raisim");
/// get target file from command line
if (argc < 2) {
std::cerr << "Please provide the path to a URDF file in the command line" << std::endl;
return 1;
}
std::string filepath = argv[1];
/// create raisim world
raisim::World world;
world.setTimeStep(0.003);
world.setGravity({0.0, 0.0, -9.81});
/// these method must be called before initApp
auto vis = raisim::OgreVis::get();
vis->setWorld(&world);
vis->setWindowSize(1024, 768);
vis->setImguiSetupCallback(imguiSetupCallback);
vis->setImguiRenderCallback(imguiRenderCallBack);
vis->setSetUpCallback(setupCallback);
vis->setKeyboardCallback(raisimKeyboardCallback);
//vis->setAntiAliasing(2);
/// init
vis->initApp();
/// create raisim objects
auto ground = world.addGround(-2.0);
vis->createGraphicalObject(ground, 20, "floor", "checkerboard_green");
/// make robot
auto robot = world.addArticulatedSystem(filepath);
auto robot_visual = vis->createGraphicalObject(robot, robot->getName());
/// info
std::cout << "Robot: " << robot->getName() << std::endl;
std::cout << "DOF: " << robot->getDOF() << std::endl;
std::cout << "n(q): " << robot->getGeneralizedCoordinateDim() << std::endl;
/// set camera
vis->getCameraMan()->getCamera()->setPosition(0, 2.0, 1.0);
vis->getCameraMan()->getCamera()->pitch(Ogre::Radian(1.2));
vis->select(robot_visual->at(0));
vis->getCameraMan()->setYawPitchDist(Ogre::Radian(0.), Ogre::Radian(-1.5), 5);
/// run the app
vis->run();
/// terminate
vis->closeApp();
return 0;
}
When I was installing Ogre by running:
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$LOCAL_INSTALL -DOGRE_BUILD_COMPONENT_BITES=ON -OGRE_BUILD_COMPONENT_JAVA=OFF -DOGRE_BUILD_DEPENDENCIES=OFF -DOGRE_BUILD_SAMPLES=False
Cmake gave an error "Unknown argument -OGRE_BUILD_COMPONENT_JAVA=OFF". After I just deleted this argument, it seemed to work. Any reason why?
I am on Ubuntu 16.04.
Unfortunately when I try to run the examples (./anymal
in particular) after the install on my ubuntu 20.04 LTS system I get one of the following two errors:
[2021:10:14:18:42:28 OgreVis.hpp:351] Loading RaisimOgre Resources from:
[2021:10:14:18:42:28 OgreVis.hpp:352] Loading OGRE Configurations from: /home/manu/src/raisim_ws/raisimOgre/build/
Segmentation fault (core dumped)
[2021:10:14:18:43:42 OgreVis.hpp:351] Loading RaisimOgre Resources from:
[2021:10:14:18:43:42 OgreVis.hpp:352] Loading OGRE Configurations from: /home/manu/src/raisim_ws/raisimOgre/build/
[2021:10:14:18:43:42 OgreVis.cpp:893] unsupported visual shape of ANYmal_0 of
When investigating it further and trying to run the example with GDB I get:
Thread 1 "anymal" received signal SIGSEGV, Segmentation fault.
__memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:436
436 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: No such file or directory.
(gdb) bt
#0 __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:436
#1 0x00007ffff75c7b28 in std::basic_streambuf<char, std::char_traits<char> >::xsputn(char const*, long) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#2 0x00007ffff75b9824 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7f9b016 in std::operator<< <char, std::char_traits<char>, std::allocator<char> > (__str=<error: Cannot access memory at address 0x37>, __os=...)
at /usr/include/c++/9/bits/basic_string.h:6416
#4 raisim::OgreVis::registerRaisimGraphicalObjects (this=0x555555591e30, vo=..., graphics=std::vector of length 0, capacity 0, as=0x5555562aa020, name="ANYmal_0", group=1)
at /home/manu/src/raisim_ws/raisimOgre/src/OgreVis.cpp:893
#5 0x00007ffff7f9b61c in raisim::OgreVis::createGraphicalObject (this=0x555555591e30, as=0x5555562aa020, name="ANYmal") at /usr/include/c++/9/bits/char_traits.h:300
#6 0x000055555555b83f in main ()
Do you have any idea why this might be the case?
Could it have to do with my LOCAL_INSTALL directory? I installed raisimLib, ogre and raisimOgre all in /opt/raisimOgre
. is that the intended way? Or should raisimLib be installed separately from the others?
Any help is appreciated! let me know if more information is required.
Hello again Jemin
Faced the problem:
Traceback (most recent call last):
File "runner.py", line 2, in <module>
from raisimGymTorch.env.bin import rsg_a1
ImportError: /raisim_workspace/raisimLib/raisimGymTorch/raisimGymTorch/env/bin/rsg_a1.cpython-36m-x86_64-linux-gnu.so: undefined symbol: _ZN6raisim7OgreVis12singletonPtrE
I have seen other issues, but they are not applicable in my situation.
I only have python 3.6 in docker and only use that. Also tested other python versions (3.7 and 3.8) with a complete docker reinstall.
I can't even imagine possible solutions to the problem. Thanks in advance for your patience.
I got an error message:
[2021:07:28:02:15:24 OgreVis.hpp:350] Loading RaisimOgre Resources from:
[2021:07:28:02:15:24 OgreVis.hpp:351] Loading OGRE Configurations from: /home/seop/raisim_env/raisim_build/share/raisimOgre/cmake/../ogre/
X Error of failed request: BadValue (integer parameter out of range for operation)
Major opcode of failed request: 152 (GLX)
Minor opcode of failed request: 3 (X_GLXCreateContext)
Value in failed request: 0x0
Serial number of failed request: 107
Current serial number in output stream: 108
I cannot sure what is the exact reason of this error.
How could I fix this?
Hi Raisim Tech Team,
I am using raisim with ogre and I noticed that visualization of height map segfaults when the number of threads in the environment config file is more than 1. With a single thread the problem does not happen. The problem seems to be in OgreVis.cpp in "remove" function. Looks like the line 467 in OgreVis.cpp causes the problem. Looking at the line 466, it seems that the mesh is being removed if it hasn't been found in the map:
primitiveMeshNames_.find(go.meshName) == primitiveMeshNames_.end()
I was wondering whether that line should be changed to:
primitiveMeshNames_.find(go.meshName) != primitiveMeshNames_.end()
When I change the comparison sign from ==
to !=
the problem does not happen anymore no matter what the number of threads.
Thank you for your help.
Best,
Edo
Hi I'm trying to render on raisimOgre, for RaiSim 1.0.0 version.
I was sequentially compiling raisimLib -> ogre -> raisimogre -> pybind11 into my $ LOCAL_BUILD.
I go to the raisimGymTorch folder and add a line to setup.py:
__CMAKE_PREFIX_PATH__ = '/home/roman/unia1/raisim_build'
I go along the path raisimLib/raisimGymTorch/raisimGymTorch/env/envs/rsg_a1
...
├── cfg.yaml
├── Environment.hpp
├── runner.py
├── tester.py
└── visSetupCallback.hpp
In Environment.hpp, I add the line:
#include "visSetupCallback.hpp"
or #include "OgreVis.hpp"
or #include "raisim/OgreVis.hpp"
I run setup.py:
sudo python3 setup.py develop
And the error appears:
home/roman/unia1/raisim_workspace/raisimLib/raisimGymTorch/raisimGymTorch/env/envs/rsg_a1/visSetupCallback.hpp: 28: 10: fatal error: raisim/OgreVis.hpp: No such file or directory
#include <raisim/OgreVis.hpp>
^~~~~~~~~~~~~~~~~~~~
With all this, in the /home/roman/unia1/raisim_build/include/raisim folder, I see the OgreVis.hpp file.
What could be the problem and how to solve it?
Hello, Jemin
I am trying to find your old repository. I am interested in the file where there is this simulation:
https://raisim.com/_images/raisimGymTorch_trainedPolicy2.gif
Where can I find information on connecting RaiSim and ROS? Or information on importing data to a real robot?
Thanks in advance!
Would it be possible to have a 'sensible default' for activation key location?
Or even multiple search locations?
e.g.:
Hello,
I have been trying hard to install raisimOgre but ogre "make" throws errors. While I have seen the previous issue where it is suggested to use RaisimUnity, I must use RaisimOgre since all the work in my research group is based on it. I am attaching herewith the console output of the make install -j8
command for Ogre. I request your assistance!
Seems like scaling function in addMesh() in raisimOgre/examples/src/mesh/meshes.cpp is not working.
CMake Error at CMakeLists.txt:12 (find_package):
Could not find a package configuration file provided by "raisim" (requested
version 0.6.0) with any of the following names:
raisimConfig.cmake
raisim-config.cmake
Add the installation prefix of "raisim" to CMAKE_PREFIX_PATH or set
"raisim_DIR" to a directory containing one of the above files. If "raisim"
provides a separate development package or SDK, be sure it has been
installed.
-- Configuring incomplete, errors occurred!
Hello! When I compile the raisimOgre
by running the last step —— “make install -j8”, I find the following error and fail to compile it:
[ 81%] Building CXX object CMakeFiles/raisimOgre.dir/src/OgreVis.cpp.o
In file included from /home/weilang/raisim_build/include/raisim/math/Core.hpp:13,
from /home/weilang/raisim_build/include/raisim/math.hpp:17,
from /home/weilang/raisim_build/include/raisim/object/Object.hpp:12,
from /home/weilang/raisim_build/include/raisim/World.hpp:13,
from /home/weilang/raisim_workspace/raisimOgre/include/raisim/interfaces.hpp:12,
from /home/weilang/raisim_workspace/raisimOgre/include/raisim/OgreVis.hpp:29,
from /home/weilang/raisim_workspace/raisimOgre/src/OgreVis.cpp:15:
/home/weilang/raisim_build/include/raisim/math/Matrix.hpp: In instantiation of ‘raisim::Mat<n, m>::Mat(const T2&) [with T2 = raisim::Mat<3, 1>*; long unsigned int n = 3; long unsigned int m = 1]’:
/home/weilang/raisim_workspace/raisimOgre/src/OgreVis.cpp:1271:75: required from here
/home/weilang/raisim_build/include/raisim/math/Matrix.hpp:55:117: error: expression cannot be used as a function
55 | Mat(const T2 &rhs) { for (size_t i = 0; i < rows(); ++i) for (size_t j = 0; j < cols(); ++j) operator()(i,j) = rhs(i,j); }
| ~~~^~~~~
make[2]: *** [CMakeFiles/raisimOgre.dir/build.make:154: CMakeFiles/raisimOgre.dir/src/OgreVis.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:207: CMakeFiles/raisimOgre.dir/all] Error 2
make: *** [Makefile:130: all] Error 2
(From 70b753d68145fc2868ab5921a30fced7891dc7f2
)
Hi Raisim Tech,
recently I was subscribing the joint angles of the quadruped from a ros topic and then use them as PdTarget for the Raisim. From that topic I can not only read the ros::time but also joint angles of the robot. I used the setPdTarget in a while loop like this:
while (ros::ok()){
world.setTimeStep((raisim_PD.timeStamp - lastTimeStampt).toSec());
lastTimeStampt = raisim_PD.timeStamp;
// prepares all kinematic and dynamic quantities for the current time step
world.integrate1();
jointsPTarget << 0, 0, 0, 0, 0, 0, 0,
raisim_PD.joints[0], raisim_PD.joints[1], raisim_PD.joints[2],
raisim_PD.joints[6], raisim_PD.joints[7], raisim_PD.joints[8],
raisim_PD.joints[3], raisim_PD.joints[4], raisim_PD.joints[5],
raisim_PD.joints[9], raisim_PD.joints[10], raisim_PD.joints[11];
anymal.back()->setPdTarget(jointsPTarget, jointVelocityTarget);
// actually move time foward and change the state
world.integrate2();
vis->renderOneFrame();
ros::spinOnce();
}
I realized that the "vis->renderOneFrame();" took more time than my subscription frequency so that my whole PD controller target setting frequency for Raisim was also reduced. I was wondering can I also run the renderOneFrame command in a separate loop so that it won't reduce my controller's frequency?
Thank you in advance.
Best
Dear RaiSim Team,
As discussed in #23, it is impossible to render two different images for the simulation. But I wonder if it is possible to add a stereo camera view for the simulator? Because we are gonna obtain a stereo camera view from RaiSim and use it to get the depth info. Thanks for any feedback.
Best
From 3a77c7c71c11348ecdcb5b73dc42a5549c6184b2
,
the height map is not visualized correctly.
When trying to compile my Raisim application I get the following error:
/usr/bin/ld: CMakeFiles/gambol.dir/src/RaiSimViewer.cpp.o:(.bss+0x0): multiple definition of `raisim::OgreVis::singletonPtr'; CMakeFiles/gambol.dir/src/main.cpp.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
This happens when I try to use OgreVis
through an intermediate class:
// main.h
#include "MyViewer.h"
int main() {
MyViewer viewer();
}
// MyViewer.h
#ifndef SRC_RAISIMVIEWER_H_
#define SRC_RAISIMVIEWER_H_
#include <raisim/OgreVis.hpp>
class RaiSimViewer {
};
#endif //SRC_RAISIMVIEWER_H_
// MyViewer.cpp
#include "RaiSimViewer.h"
// Empty, no definitions yet
The kicker is: the program compiles when I comment out the #include "RaiSimViewer.h"
in MyViewer.cpp
.
Note that I can build and run the examples without any problems.
I pulled, build and installed the latest versions of raisimLib and ogre.
And for completeness also make CMakeLists.txt
:
cmake_minimum_required(VERSION 3.10.0)
project(Gambol VERSION 1.0.0 DESCRIPTION "Gait optimization platform")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Ofast")
set(CMAKE_CXX_STANDARD 14)
# Other packages
find_package(raisimOgre CONFIG REQUIRED)
find_package(Eigen3 REQUIRED NO_MODULE)
# Define output
add_executable(gambol src/main.cpp src/RaiSimViewer.cpp src/RaiSimViewer.h)
# Link libraries to output
target_link_libraries(gambol PUBLIC
raisim::raisimOgre
Eigen3::Eigen)
Hi there,
thanks for the awesome library.
Recently, I try to control the ANYmal C in raisimOgre. I want to have two different views: one is from an arbitrary direction which can see the ANYmal, where the other one is the view from the front camera. I tried initializing two separate visualizers, and always set the CameraMan position and orientation exactly the same as the front camera. However, it seems that I can only run one visualizer at one time. So I was wondering is it possible to add an additional camera view in raisimOgre?
Many Thanks
Shengzhi
After running the command line "make install -j8",It has already reached 100%, but error happens when installing
libOgreMain.so.1.12.2 no such file or directory
Dear Raisim Team,
I wanna change the friction coefficient between the robot's feet with the gound in RaisimOgre to a really small value. I have followed the tutorial here. The codes I tried are:
auto ground = world.addGround(0, "checkerboard_green");
// Set friction coefficient
anymal.back()->getCollisionBody("LF_FOOT/0").setMaterial("LF_FOOT");
anymal.back()->getCollisionBody("RF_FOOT/0").setMaterial("RF_FOOT");
anymal.back()->getCollisionBody("LH_FOOT/0").setMaterial("LH_FOOT");
anymal.back()->getCollisionBody("RH_FOOT/0").setMaterial("RH_FOOT");
world.setMaterialPairProp("checkerboard_green", "LF_FOOT", 0.1, 0, 0);
world.setMaterialPairProp("checkerboard_green", "RF_FOOT", 0.1, 0, 0);
world.setMaterialPairProp("checkerboard_green", "LH_FOOT", 0.1, 0, 0);
world.setMaterialPairProp("checkerboard_green", "RH_FOOT", 0.1, 0, 0);
Also, I tried these:
auto ground = world.addGround(0, "checkerboard_green");
// Set friction coefficient
anymal.back()->getCollisionBody("LF_FOOT/0").setMaterial("LF_FOOT");
anymal.back()->getCollisionBody("RF_FOOT/0").setMaterial("RF_FOOT");
anymal.back()->getCollisionBody("LH_FOOT/0").setMaterial("LH_FOOT");
anymal.back()->getCollisionBody("RH_FOOT/0").setMaterial("RH_FOOT");
world.setMaterialPairProp("checkerboard_green", "LF_FOOT", 0.1, 0.15, 0.001, 0.1, 0.001);
world.setMaterialPairProp("checkerboard_green", "RF_FOOT", 0.1, 0.15, 0.001, 0.1, 0.001));
world.setMaterialPairProp("checkerboard_green", "LH_FOOT", 0.1, 0.15, 0.001, 0.1, 0.001));
world.setMaterialPairProp("checkerboard_green", "RH_FOOT",0.1, 0.15, 0.001, 0.1, 0.001));
But when the robot walked on the ground, it seems that the friction coefficient didn't change because the feet didn't get slid. Did I do the correct way to change the coefficient?
Best
OS: ubunut 20.04
CPU: AMD R7 4700H
GPU: RTX 2060
g++: version is 9.0
swig:7: error: pcre regex matching is not available in this swig build.
this problem happened when runmake install -j4
after the cmake
using g++-8
rather than g++-9
Hi,
When I play with atlas example, I found very strange contact point inside knee and waist, which are not collided with ground or in self-collision.
I uploaded screenshots here.
Thank you!
Fan
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.