rst-tu-dortmund / costmap_converter Goto Github PK
View Code? Open in Web Editor NEWA ros package that includes plugins and nodes to convert occupied costmap2d cells to primitive types
A ros package that includes plugins and nodes to convert occupied costmap2d cells to primitive types
Hi,
Could it be interesting and possible to refactor this repo into a meta-package with clearly separated 'core' (base classes) package and plugins packages ??
This would ease its compilation, use and make the licenses distinction more clear.
Thanks.
With the current ROS2 and Navigation2 master I am unable to load any of the costmap converter plugins.
I'm using the "ros2" branch of this repo and "ros2-master" of the TEB planner.
This is the error message I'm getting:
[controller_server-9] [INFO] [1590755915.374223651] [controller_server]: The specified costmap converter plugin cannot be loaded. All occupied costmap cells are treaten as point obstacles. Error message: MultiLibraryClassLoader: Could not create object of class type costmap_converter::CostmapToLinesDBSRANSAC as no factory exists for it. Make sure that the library exists and was explicitly loaded through MultiLibraryClassLoader::loadLibrary()
costmap_converter_loader_.getDeclaredClasses() returns:
[controller_server-9] Available Plugins: costmap_converter::CostmapToDynamicObstacles
[controller_server-9] Available Plugins: costmap_converter::CostmapToLinesDBSMCCH
[controller_server-9] Available Plugins: costmap_converter::CostmapToLinesDBSRANSAC
[controller_server-9] Available Plugins: costmap_converter::CostmapToPolygonsDBSConcaveHull
[controller_server-9] Available Plugins: costmap_converter::CostmapToPolygonsDBSMCCH
costmap_converter_loader_.isClassAvailable("costmap_converter::CostmapToLinesDBSRANSAC") returns true
but costmap_converter_loader_.getRegisteredLibraries() returns nothing.
Already contain the orientation, so...
Sure, we can recalculate it, but why to do twice
Hey,
Is it possible to release this package for foxy? The ros2
branch is working fine from source.
Thanks!
C:\ws\turtlebot3\src\costmap_converter\include\costmap_converter\costmap_to_polygons.h(305) : error C4716: 'costmap_converter::CostmapToPolygonsDBSMCCH::pointToNeighborCells': must return a value
The above error can be fixed by changing the return type to void in the function pointToNeighborCells in the costmap_to_polygons.h and recompiling.
How could a circle be describe with the ObstacleMsg.msg
??
As of now and since we are dealing with 2D I use a single geometry_msgs/Point32
in the polygon where its x
& y
component describe the circle center and its z
component describe its radius.
This is a bit hacky but is there a better way ??
This is a valgrind output when the application crashed due to some memory leak with allocation. This happens only when using costmap_converter::CostmapToLinesDBSMCCH
==130793== Thread 12:
==130793== Invalid read of size 8
==130793== at 0x4842A8F: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==130793== by 0x10EB878E: costmap_converter::CostmapToLinesDBSMCCH::extractPointsAndLines(std::vector<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint, std::allocator<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint> >&, geometry_msgs::Polygon_<std::allocator<void> > const&, std::back_insert_iterator<std::vector<geometry_msgs::Polygon_<std::allocator<void> >, std::allocator<geometry_msgs::Polygon_<std::allocator<void> > > > >) (in /home/a/catkin_ws/devel/lib/libcostmap_converter.so)
==130793== by 0x10EB8CD6: costmap_converter::CostmapToLinesDBSMCCH::compute() (in /home/a/catkin_ws/devel/lib/libcostmap_converter.so)
==130793== by 0x4ADC867: ros::TimerManager<ros::Time, ros::Duration, ros::TimerEvent>::TimerQueueCallback::call() (in /opt/ros/noetic/lib/libroscpp.so)
==130793== by 0x4AFEE61: ros::CallbackQueue::callOneCB(ros::CallbackQueue::TLS*) (in /opt/ros/noetic/lib/libroscpp.so)
==130793== by 0x4B00372: ros::CallbackQueue::callAvailable(ros::WallDuration) (in /opt/ros/noetic/lib/libroscpp.so)
==130793== by 0x1074A96C: costmap_converter::BaseCostmapToPolygons::spinThread() (in /opt/ros/noetic/lib/libteb_local_planner.so)
==130793== by 0x525443A: ??? (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.71.0)
==130793== by 0x517D608: start_thread (pthread_create.c:477)
==130793== by 0x4F75102: clone (clone.S:95)
==130793== Address 0xb70c130 is 0 bytes after a block of size 64 alloc'd
==130793== at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==130793== by 0x10E9FBB8: void std::vector<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint, std::allocator<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint> >::_M_realloc_insert<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint const&>(__gnu_cxx::__normal_iterator<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint*, std::vector<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint, std::allocator<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint> > >, costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint const&) (in /home/a/catkin_ws/devel/lib/libcostmap_converter.so)
==130793== by 0x10E9082C: costmap_converter::CostmapToPolygonsDBSMCCH::dbScan(std::vector<std::vector<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint, std::allocator<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint> >, std::allocator<std::vector<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint, std::allocator<costmap_converter::CostmapToPolygonsDBSMCCH::KeyPoint> > > >&) (in /home/a/catkin_ws/devel/lib/libcostmap_converter.so)
Building the package from source with Clang 15 and OpenCV 4.7.0 built from source on Ubuntu 22.04 LTS and Mint 22 the following line 9 in src/costmap_to_dynamic_obstacles/blob_detector.cpp
:
return cv::Ptr<BlobDetector> (new BlobDetector(params)); // compatibility with older versions
produces the error: BlobDetector: attempt to instantiate an abstract class
, because BlobDetector
is inherited from cv::SimpleBlobDetector
now containing abstract member functions. To harmonize the smart OpenCV pointers instantiation here, the following workaround is used:
cv::Ptr<BlobDetector> BlobDetector::create(const cv::SimpleBlobDetector::Params& params)
{
// return cv::Ptr<BlobDetector> (new BlobDetector(params)); // compatibility with older versions
return cv::Ptr<BlobDetector>(dynamic_cast<BlobDetector*>(cv::SimpleBlobDetector::create(params).get()));
}
Could anyone please help me figure out the OpenCV version from which this error appears? Then I will create a pull request with proper definitions to handle the issue.
Hi,
I am trying to use the costmap_converter. I am publishing a costmap with costmap_2d API. And then launching the costmap_converter to publish an obstacle list based on that costmap. How to tune the costmap_converter plugins to give a single obstacle instead of a list of polygons? I am looking for a boundingSphere. As you can see, it is a single object but it publish a several obstacles.
Thanks in advance!
To release TEB, this needs to be released first
Hi,
We notice that you are using topic names from ROS parameters at the following locations:
Although parameters are usually set in parameter files, they can also be changed by nodes. Specifically, other nodes in the same ROS application can also change the parameters listed above before it’s used, either by accident or intentionally (i.e., by potential attackers). If any of /move_base/local_costmap/costmap
, /move_base/local_costmap/costmap_updates
, or /odom
parameters is changed, the costmap_converter_node will subscribe to the wrong input topics and will fail to read the input data. Moreover, if an attacker exists, she can even first fool the costmap_convert_node to subscribe to a wrong topic like /odom_fake
, and then forward messages from /odom
to /odom_fake
after changing the message contents, which gives the attacker the capability of changing the obstacle positions through the composition of ego motion. The victim robot may navigate to the wrong destinations, and even crash into obstacles. Similarly, the obstacle publisher and marker publisher can also be affected or attacked using the man-in-the-middle way. Because ROS is an OSS (open-source software) community, third-party nodes are widely used in ROS applications, usually without complete vetting of their behavior, which gives the opportunity to potentially malicious actors to inject malicious code (e.g, by submitting hypocrite commits like in other OSS systems [1]) to infiltrate the ROS applications that use it (or software supply chain attacks, one of the primary means for real-world attackers today [2]).
We understand that using parameters to set topic names brings flexibility. Still, for the purpose of security, we strongly suggest that you avoid such vulnerable programming patterns if possible. For example, to avoid the exposure of this specific vulnerability, you may consider alternatives like remapping, which is designed for configuring names when launching the nodes.
[1] Q. Wu and K. Lu, “On the feasibility of stealthily introducing vulnerabilities in open-source software via hypocrite commits,” 2021, https://linuxreviews.org/images/d/d9/OpenSourceInsecurity.pdf.
[2] Supply chain attacks are the hacker’s new favourite weapon. and the threat is getting bigger. https://www.zdnet.com/article/supply-chain-attacks-are-the-hackers-new-favourite-weapon-and-the-threat-is-getting-bigger/.
Currently the converter continuously parses the costmap, even when this is stopped and didn't change from the previous execution. Since the CPU usage of most of the plugins is relevant (often consumes an entire core on our platforms), it would be useful to pause the parsing if the costmap is stopped.
Unfortunately it is currently not easy to check if the costmap is stopped; I made a PR to expose the stopped status of the costmap2D_ros here
Can you think about any alternative that could avoid this unnecessary computation? Maybe comparing the current costmap with the latest used one?
You are missing a "<build_type>ament_cmake</build_type>" above line 32.
Move base node returns:
Invalid argument "/map" passed to canTransform argument source_frame in tf2 frame_ids cannot start with a '/' like:
at line 134 in /tmp/binarydeb/ros-melodic-tf2-0.6.5/src/buffer_core.cpp
Tf2 frame cannot start with /
and in costmap_converter code /map
is hardcoded as frame_id.
Hi, I'm reporting a crash when using CostmapToDynamicObstales
plugin for navigating a Turtlebot in a custom simulation environment.
Environment:
I'm launching the Webots world in terminal1 and turtlebot3_navigation2 navigation2.launch.py in terminal 2. This works correctly.
Then, If I run the standalone_converter node with CostmapToDynamicObstales
plugin from terminal 3, using gdb debug I get this:
matteodr@matteoNUC:~$ ros2 run --prefix 'gdb -ex run --args' costmap_converter standalone_converter --all-other-launch arguments
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
--Type <RET> for more, q to quit, c to continue without paging--RET
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/matteodr/ros2_ws/install/costmap_converter/lib/costmap_converter/standalone_converter...
(No debugging symbols found in /home/matteodr/ros2_ws/install/costmap_converter/lib/costmap_converter/standalone_converter)
--Type <RET> for more, q to quit, c to continue without paging--c
Starting program: /home/matteodr/ros2_ws/install/costmap_converter/lib/costmap_converter/standalone_converter --all-other-launch arguments
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff659d700 (LWP 11242)]
[New Thread 0x7ffff5d13700 (LWP 11243)]
[New Thread 0x7ffff5512700 (LWP 11244)]
[New Thread 0x7ffff4d11700 (LWP 11245)]
[New Thread 0x7ffff4510700 (LWP 11246)]
[New Thread 0x7ffff3d0f700 (LWP 11247)]
[New Thread 0x7ffff350e700 (LWP 11248)]
[New Thread 0x7ffff2d0d700 (LWP 11249)]
[New Thread 0x7ffff2383700 (LWP 11250)]
[New Thread 0x7ffff195e700 (LWP 11251)]
[New Thread 0x7ffff0cbc700 (LWP 11252)]
[INFO] [1625496476.614068004] [converter_costmap.converter_costmap]:
converter_costmap lifecycle node launched.
Waiting on external lifecycle transitions to activate
See https://design.ros2.org/articles/node_lifecycle.html for more information.
[INFO] [1625496476.614976255] [converter_costmap.converter_costmap]: Creating Costmap
[New Thread 0x7fffd3fff700 (LWP 11253)]
[INFO] [1625496476.620708491] [converter_costmap.converter_costmap]: Configuring
[New Thread 0x7fffd37fe700 (LWP 11254)]
[INFO] [1625496476.631328644] [converter_costmap.converter_costmap]: Using plugin "static_layer"
[INFO] [1625496476.659515564] [converter_costmap.converter_costmap]: Subscribing to the map topic (/map) with transient local durability
[INFO] [1625496476.662064688] [converter_costmap.converter_costmap]: Initialized plugin "static_layer"
[INFO] [1625496476.662098273] [converter_costmap.converter_costmap]: Using plugin "obstacle_layer"
[INFO] [1625496476.663383857] [converter_costmap.converter_costmap]: Subscribed to Topics:
[INFO] [1625496476.663492328] [converter_costmap.converter_costmap]: Initialized plugin "obstacle_layer"
[INFO] [1625496476.663522488] [converter_costmap.converter_costmap]: Using plugin "inflation_layer"
[INFO] [1625496476.664405979] [converter_costmap.converter_costmap]: Initialized plugin "inflation_layer"
[INFO] [1625496476.674781109] [converter_costmap.converter_costmap]: StaticLayer: Resizing costmap to 245 X 192 at 0.050000 m/pix
[INFO] [1625496476.680728679] [converter_costmap.converter_costmap]: Activating
[INFO] [1625496476.680761660] [converter_costmap.converter_costmap]: Checking transform
[INFO] [1625496476.680786888] [converter_costmap.converter_costmap]: Timed out waiting for transform from base_link to map to become available, tf error: Invalid frame ID "map" passed to canTransform argument target_frame - frame does not exist
[INFO] [1625496477.181059877] [converter_costmap.converter_costmap]: Timed out waiting for transform from base_link to map to become available, tf error: Lookup would require extrapolation into the past. Requested time 148.592000 but the earliest data is at time 149.176000, when looking up transform from frame [base_link] to frame [map]
[INFO] [1625496477.680919632] [converter_costmap.converter_costmap]: Timed out waiting for transform from base_link to map to become available, tf error: Lookup would require extrapolation into the past. Requested time 149.072000 but the earliest data is at time 149.176000, when looking up transform from frame [base_link] to frame [map]
[New Thread 0x7fffd2ffd700 (LWP 11255)]
[INFO] [1625496478.181705743] [converter_costmap.converter_costmap]: start
[INFO] [1625496478.726000752] [costmap_converter]: Standalone costmap converter: costmap_converter::CostmapToDynamicObstacles loaded.
[INFO] [1625496478.738832875] [costmap_converter.intra_node]: CostmapToDynamicObstacles: underlying costmap conversion plugin for static obstacles �uRVUU loaded.
[New Thread 0x7fffb7597700 (LWP 11256)]
[INFO] [1625496478.754237889] [costmap_converter.intra_node]: CostmapToDynamicObstacles: odom received.
[New Thread 0x7fffb5e08700 (LWP 11257)]
[New Thread 0x7fffb5607700 (LWP 11258)]
[New Thread 0x7fffa3fff700 (LWP 11259)]
malloc(): invalid size (unsorted)
Thread 16 "standalone_conv" received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffb7597700 (LWP 11256)]
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) backtrace
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007ffff7797859 in __GI_abort () at abort.c:79
#2 0x00007ffff78023ee in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff792c285 "%s\n")
at ../sysdeps/posix/libc_fatal.c:155
#3 0x00007ffff780a47c in malloc_printerr (str=str@entry=0x7ffff792ea50 "malloc(): invalid size (unsorted)") at malloc.c:5347
#4 0x00007ffff780d234 in _int_malloc (av=av@entry=0x7fffb0000020, bytes=bytes@entry=17856) at malloc.c:3736
#5 0x00007ffff780f419 in __GI___libc_malloc (bytes=17856) at malloc.c:3066
#6 0x00007ffff7a29b39 in operator new(unsigned long) () at /lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007ffff01d24e5 in std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >::_M_default_append(unsigned long) () at /home/matteodr/ros2_ws/install/costmap_converter/lib/libcostmap_converter.so
#8 0x00007ffff01cd7fc in costmap_converter::CostmapToPolygonsDBSMCCH::updateCostmap2D() ()
at /home/matteodr/ros2_ws/install/costmap_converter/lib/libcostmap_converter.so
#9 0x00007ffff01e27f6 in costmap_converter::CostmapToDynamicObstacles::compute() ()
at /home/matteodr/ros2_ws/install/costmap_converter/lib/libcostmap_converter.so
#10 0x00005555555734d7 in rclcpp::GenericTimer<std::_Bind<void (costmap_converter::BaseCostmapToPolygons::*(costmap_converter::BaseCostmapToPolygons*))()>, (void*)0>::execute_callback() ()
#11 0x00007ffff7ccf00d in rclcpp::Executor::execute_any_executable(rclcpp::AnyExecutable&) () at /opt/ros/foxy/lib/librclcpp.so
--Type <RET> for more, q to quit, c to continue without paging--
Everything works fine with CostmapToPolygonsDBSMCCH
plugin instead
Hello,
I want to use costmap_converter standalone node. I'm able to run it but all obstacles are doubled with a huge shift. I subsribe to costmap and costmap_update topic. Also I enabled obstacle_layer in global costmap settings.
I also note that frame_id is not set in costmap_obstacles topic even if it should according to source code. I checked rame_id of costmal and costmap_update topics, both are set to "map"
Ros Noetic
Ubuntu 20.04
OpenCV4 with cuda 11.4
Cv_bridge from source built with the above OpenCV
Error with catkin_make :
/home/axel/catkin_ws/src/costmap_converter/src/costmap_to_dynamic_obstacles/blob_detector.cpp: In static member function ‘static cv::Ptr<BlobDetector> BlobDetector::create(const cv::SimpleBlobDetector::Params&)’:
/home/axel/catkin_ws/src/costmap_converter/src/costmap_to_dynamic_obstacles/blob_detector.cpp:9:56: error: invalid new-expression of abstract class type ‘BlobDetector’
9 | return cv::Ptr<BlobDetector> (new BlobDetector(params)); // compatibility with older versions
| ^
In file included from /home/axel/catkin_ws/src/costmap_converter/src/costmap_to_dynamic_obstacles/blob_detector.cpp:1:
/home/axel/catkin_ws/src/costmap_converter/include/costmap_converter/costmap_to_dynamic_obstacles/blob_detector.h:60:7: note: because the following virtual functions are pure within ‘BlobDetector’:
60 | class BlobDetector : public cv::SimpleBlobDetector
| ^~~~~~~~~~~~
In file included from /usr/local/include/opencv4/opencv2/features2d/features2d.hpp:48,
from /home/axel/catkin_ws/src/costmap_converter/include/costmap_converter/costmap_to_dynamic_obstacles/blob_detector.h:48,
from /home/axel/catkin_ws/src/costmap_converter/src/costmap_to_dynamic_obstacles/blob_detector.cpp:1:
/usr/local/include/opencv4/opencv2/features2d.hpp:789:24: note: ‘virtual void cv::SimpleBlobDetector::setParams(const cv::SimpleBlobDetector::Params&)’
789 | CV_WRAP virtual void setParams(const SimpleBlobDetector::Params& params ) = 0;
| ^~~~~~~~~
/usr/local/include/opencv4/opencv2/features2d.hpp:790:46: note: ‘virtual cv::SimpleBlobDetector::Params cv::SimpleBlobDetector::getParams() const’
790 | CV_WRAP virtual SimpleBlobDetector::Params getParams() const = 0;
| ^~~~~~~~~
make[2]: *** [costmap_converter/CMakeFiles/costmap_converter.dir/build.make:141: costmap_converter/CMakeFiles/costmap_converter.dir/src/costmap_to_dynamic_obstacles/blob_detector.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:31884: costmap_converter/CMakeFiles/costmap_converter.dir/all] Error 2
I also added in the CMakelist.txt just to be sure :
set(_opencv_version 4)
find_package(OpenCV 4 QUIET)
if(NOT OpenCV_FOUND)
message(STATUS "Did not find OpenCV 4, trying OpenCV 3")
set(_opencv_version 3)
endif()
find_package(OpenCV ${_opencv_version} REQUIRED
COMPONENTS
opencv_core
opencv_imgproc
opencv_imgcodecs
CONFIG
)
which confirmed :
-- +++ processing catkin package: 'costmap_converter'
-- ==> add_subdirectory(costmap_converter)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- Found OpenCV: /usr/local (found suitable version "4.8.0", minimum required is "4") found components: opencv_core opencv_imgproc opencv_imgcodecs
-- costmap_converter: 2 messages, 0 services
Any hints for a fix ? Am I the only one who builds everything from source ?
Platform
Description
Branch ros2
doesn't support opencv4.2 which causes compilation to fail.
In file included from /home/runner/ros_ws/src/costmap_converter/costmap_converter/include/costmap_converter/costmap_to_dynamic_obstacles/multitarget_tracker/Ctracker.h:5,
from /home/runner/ros_ws/src/costmap_converter/costmap_converter/include/costmap_converter/costmap_to_dynamic_obstacles/costmap_to_dynamic_obstacles.h:62,
from /home/runner/ros_ws/src/costmap_converter/costmap_converter/src/costmap_to_dynamic_obstacles/costmap_to_dynamic_obstacles.cpp:1:
/home/runner/ros_ws/src/costmap_converter/costmap_converter/include/costmap_converter/costmap_to_dynamic_obstacles/multitarget_tracker/Kalman.h:6:10: fatal error: opencv/cv.h: No such file or directory
6 | #include <opencv/cv.h>
| ^~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/costmap_converter.dir/build.make:132: CMakeFiles/costmap_converter.dir/src/costmap_to_dynamic_obstacles/costmap_to_dynamic_obstacles.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:147: CMakeFiles/costmap_converter.dir/all] Error 2
make: *** [Makefile:158: all] Error 2
Solution
Similar issue fixed by #18 on master
, applying PR on ros2
branch or cherry-picking abf10d7 fixes the issue
Just wondering if this repo is still maintained or else if one should work on his own fork ?? (@croesmann )
With the default behavior of costmap_2d, the standalone converter appears to do nothing. No polygon markers are published. This is because he standalone converter subscribes only to the topic /move_base/local_costmap/costmap
By default the costmap is published once on that topic, and then forever as updates on /move_base/local_costmap/costmap_updates. The static_layer in costmap_2d has an example of subscribing to updates
A workaround is to set the parameter always_send_full_costmap on the local_costmap to True.
Are there plans for supporting obstacles with variable velocity?
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.