GithubHelp home page GithubHelp logo

revextensions2's People

Contributors

rbrott avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

revextensions2's Issues

FTC SDK 4.x support

Using RE2 with FTC SDK 4.x leads to errors like the following:

Process: com.qualcomm.ftcrobotcontroller, PID: 18716
    java.lang.NoSuchMethodError: No interface method getMotorType()Lcom/qualcomm/robotcore/hardware/configuration/MotorConfigurationType; in class Lcom/qualcomm/robotcore/hardware/DcMotor; or its super classes (declaration of 'com.qualcomm.robotcore.hardware.DcMotor' appears in /data/app/com.qualcomm.ftcrobotcontroller-2/base.apk:classes2.dex)
        at org.openftc.revextensions2.ExpansionHubMotor.<init>(ExpansionHubMotor.java:42)
        at org.openftc.revextensions2.Utils.hotswapHardwareMap(Utils.java:89)
        at org.openftc.revextensions2.RevExtensions2.init(RevExtensions2.java:42)

Closer inspection suggests that there are a number of breaking API changes in 4.x that affect RE2.

What happens if you call getBulkInputData() multiple times?

We have created several sub-system classes that utilize sensor data from the expansion hub. We have switched to getting this data using getBulkinputData(). Does the logic of getBulkInputData() have any logic to ensure multiple hardware calls are being made in a given "update cycle" or do we need to figure that out in our implementation?

How to change the type of expansion hub

Hello, I am just starting out with this repository and am getting an error about being unable to find our hardware device even though it is named properly on both the phone and the config. Since this is the case I assumed it was the type of expansion hub which is calls for the ExpansionHubEx type. Is this a thing specific for the phone or is it done physically in the code. Any help would be appreciate. Thanks!

Errors finding ExpansionHubEx

It seems like there are issues calling hub = hardwareMap.get(ExpansionHubEx.class, "Expansion Hub 2"); when things aren't "ready". Specifically we receive errors that the device is missing.

OpModeType: LinearOpMode
When call is made: top of runOpMode()
SDK: 5.2
RevExtensions2: 1.2

Scenario1
If we have just deployed code and we connect the hardware back.

Scenario2
Something causes the Robot Controller to reboot.

Scenario3
You disconnect the USB and connect it again.

Resolution
To fix these issues we terminate the Robot Controller app, disconnect the USB, restart the robot hardware. Start the Robot Controller app and wait for it to be completely up (error showing missing hardware), turn on the robot hardware, connect the USB.

Potential Fix
We noticed that in SDK 5.3 there are some fixes to for the external USB Web Cam. Perhaps if we upgrade to the newer version of the SDK it will resolve this?

We also saw references to calling RevExtensions2 init(), but they suggest that you no longer need to do this.

Exception when recovering form Expansion Hub coms reset

I'm using REVExtensions to speed up encoder reads on my two expansion hubs.

Occasionally I get an exception which appears to think it's a SDK mismatch, but clearly it's more than that.

When I get an expansion hub USB timeout that disconnects and then reconnects while my Teleop is running, I get the following exception:

RE2Exception - Failed to reflect on LynxController! This probably means that you're running a newer version of the SDK then I tested with and the Tech Team broke something :(

When I step beyond the dig at my team, I suppose that there must be some transitory period where the interface returns an invalid object that is being treated as an exception....

Is there a clean way to detect/recover from this?
Notice the dropout after 4 minutes of running teleop...
The system hickups and appears to recover, but the module attach then triggers the exception.
see 16:55:49.535



-27 16:51:19.191 10131 10211 V Robocol : received command: CMD_RUN_OP_MODE(13173) 2818 TELEOP
02-27 16:51:19.241 10131 10216 V Robocol : sending CMD_NOTIFY_RUN_OP_MODE(3468), attempt: 0
02-27 16:55:46.170 10131 10374 V LynxModule: retransmitting: mod=3 cmd=0x1000 msg#=101 ref#=0 
02-27 16:55:46.372 10131 10214 E MonitoredUsbDeviceConnection: watchdog: stuck USB write(11 bytes) threadId=847 TID=10374:: serial=DQ15NX6V closing device
02-27 16:55:46.373 10131 10214 V FtDevice: vv********************DQ15NX6V closing********************vv 0x02d0f205
02-27 16:55:46.373 10131 10214 V FtDevice: DQ15NX6V stopping thread readBufferManager
02-27 16:55:46.374 10131 10213 V FtDevice: DQ15NX6V thread readBufferManager is stopped
02-27 16:55:46.375 10131 10214 V FtDevice: DQ15NX6V stopping thread bulkPacketInWorker
02-27 16:55:46.375 10131 10229 V RobotCore: event loop: device has shutdown abnormally: ABNORMAL
02-27 16:55:46.376 10131 10229 V EventLoopManager: event loop: detaching device DQ15NX6V
02-27 16:55:46.376 10131 10229 I FtcEventLoop: vv===== MODULE DETACH RECOVERY: disarm REV Robotics USB Expansion Hub Portal [DQ15NX6V]=====vv
02-27 16:55:46.381 10131 10229 V LynxUsb : disarmDevice() serial=DQ15NX6V...
02-27 16:55:46.383 10131 10215 V RobotCore: thread: ...terminating 'lynx incoming datagrams'
02-27 16:55:46.383 10131 10229 V LynxUsb : shutting down incoming datagrams
02-27 16:55:46.386 10131 10229 V RobotUsbDeviceFtdi: closing DQ15NX6V
02-27 16:55:47.420 10131 10214 V MonitoredUsbDeviceConnection: closing UsbDeviceConnection(DQ15NX6V)
02-27 16:55:47.421 10131 10214 D UsbDeviceConnectionJNI: close
02-27 16:55:47.421 10131 10214 V FtDevice: ^^********************DQ15NX6V closed ********************^^
02-27 16:55:47.422 10131 10229 V LynxUsb : ...done disarmDevice()
02-27 16:55:47.422 10131 10212 E BulkPacketInWorker: DQ15NX6V: bulkTransfer() error: -1
02-27 16:55:47.423 10131 10212 V FtDevice: DQ15NX6V thread bulkPacketInWorker is stopped
02-27 16:55:47.423 10131 10229 I FtcEventLoop: ======= MODULE DETACH RECOVERY: pretend REV Robotics USB Expansion Hub Portal [DQ15NX6V]=======
02-27 16:55:47.424 10131 10374 E RobotCore: lynx xmit lock: #### releasing ownerless message keyed lock: ignored: LynxGetBulkInputDataCommand
02-27 16:55:47.424 10131 10374 E RobotCore: exception thrown during lynx communication
02-27 16:55:47.425 10131 10229 V LynxUsb : doPretend() serial=DQ15NX6V
02-27 16:55:47.427 10131 10229 I FtcEventLoop: ^^===== MODULE DETACH RECOVERY: complete REV Robotics USB Expansion Hub Portal [DQ15NX6V]=====^^
02-27 16:55:47.433 10131 10374 E RobotCore: java.lang.NullPointerException: Attempt to invoke interface method 'boolean com.qualcomm.robotcore.hardware.usb.RobotUsbDevice.isAttached()' on a null object reference
02-27 16:55:47.436 10131 10374 E RobotCore: 	at com.qualcomm.hardware.lynx.LynxUsbDeviceImpl.shutdownAbnormally(LynxUsbDeviceImpl.java:827)
02-27 16:55:47.438 10131 10374 E RobotCore: 	at com.qualcomm.hardware.lynx.LynxUsbDeviceImpl.transmit(LynxUsbDeviceImpl.java:793)
02-27 16:55:47.440 10131 10374 E RobotCore: 	at com.qualcomm.hardware.lynx.LynxUsbDeviceDelegate.transmit(LynxUsbDeviceDelegate.java:192)
02-27 16:55:47.441 10131 10229 D RobotCore: system telemetry: key=$System$Warning$ msg="problem with "Expansion Hub DC Motor Controller [USB DQ15NX6V; module 3]"; problem with "Expansion Hub Servo Controller [USB DQ15NX6V; module 3]"; problem with "Expansion Hub Voltage Sensor [USB DQ15NX6V; module 3]"; problem with "Expansion Hub Pwm Controller [USB DQ15NX6V; module 3]"; problem with "Expansion Hub Analog Input Controller [USB DQ15NX6V; module 3]"; problem with "Expansion Hub Digital Channel Controller [USB DQ15NX6V; module 3]"; problem with "imu"; problem with "Expansion Hub DC Motor Controller [USB DQ15NX6V; module 4]"; problem with "Expansion Hub Servo Controller [USB DQ15NX6V; module 4]"; problem with "Expansion Hub Voltage Sensor [USB DQ15NX6V; module 4]"; problem with "Expansion Hub Pwm Controller [USB DQ15NX6V; module 4]"; problem with "Expansion Hub Analog Input Controller [USB DQ15NX6V; module 4]"; problem with "Expansion Hub Digital Channel Controller [USB DQ15NX6V; module 4]""
02-27 16:55:47.441 10131 10374 E RobotCore: 	at com.qualcomm.hardware.lynx.LynxModule.retransmit(LynxModule.java:1393)
02-27 16:55:47.443 10131 10374 E RobotCore: 	at com.qualcomm.hardware.lynx.commands.LynxRespondable.awaitAndRetransmit(LynxRespondable.java:365)
02-27 16:55:47.444 10131 10374 E RobotCore: 	at com.qualcomm.hardware.lynx.commands.LynxRespondable.awaitAckResponseOrNack(LynxRespondable.java:373)
02-27 16:55:47.445 10131 10374 E RobotCore: 	at com.qualcomm.hardware.lynx.commands.LynxRespondable.sendReceive(LynxRespondable.java:253)
02-27 16:55:47.446 10131 10374 E RobotCore: 	at org.openftc.revextensions2.ExpansionHubEx.getBulkInputData(ExpansionHubEx.java:440)
02-27 16:55:47.448 10131 10374 E RobotCore: 	at org.firstinspires.ftc.teamcode.Hardware_GFORCE.readEncoders(Hardware_GFORCE.java:384)
02-27 16:55:47.449 10131 10374 E RobotCore: 	at org.firstinspires.ftc.teamcode.Hardware_GFORCE.runPIDs(Hardware_GFORCE.java:726)
02-27 16:55:47.450 10131 10374 E RobotCore: 	at org.firstinspires.ftc.teamcode.TELEOP.runOpMode(TELEOP.java:143)
02-27 16:55:47.450 10131 10374 E RobotCore: 	at com.qualcomm.robotcore.eventloop.opmode.LinearOpMode$LinearOpModeHelper$1.run(LinearOpMode.java:305)
02-27 16:55:47.451 10131 10374 E RobotCore: 	at com.qualcomm.robotcore.util.ThreadPool.logThreadLifeCycle(ThreadPool.java:737)
02-27 16:55:47.451 10131 10374 E RobotCore: 	at com.qualcomm.robotcore.eventloop.opmode.LinearOpMode$LinearOpModeHelper.run(LinearOpMode.java:300)
02-27 16:55:47.453 10131 10374 E RobotCore: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
02-27 16:55:47.454 10131 10374 E RobotCore: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
02-27 16:55:47.454 10131 10374 E RobotCore: 	at com.qualcomm.robotcore.util.ThreadPool$ThreadFactoryImpl$1.run(ThreadPool.java:793)
02-27 16:55:47.455 10131 10374 E RobotCore: 	at java.lang.Thread.run(Thread.java:761)
02-27 16:55:47.512 10131 10220 V SoundInfo: construct(0x075715f4)
02-27 16:55:47.565 10131 10219 I MediaCodec: (0x96cdbe00) init name(audio/raw) isType(1) encoder(0)
02-27 16:55:47.570 10131 10383 I MediaCodec: (0x96cdbe00) Component Allocated (OMX.google.raw.decoder)
02-27 16:55:47.571 10131 10219 I MediaCodec: (0x96cdbe00) configure surface(0x0) crypto(0x0) flags(0)
02-27 16:55:47.571 10131 10219 D MediaCodec: (0x96cdbe00) configure format: AMessage(what = 0x00000000) = {
02-27 16:55:47.571 10131 10219 D MediaCodec:       string mime = "audio/raw"
02-27 16:55:47.571 10131 10219 D MediaCodec:       int64_t durationUs = 1043650
02-27 16:55:47.571 10131 10219 D MediaCodec:       int32_t track-id = 1
02-27 16:55:47.571 10131 10219 D MediaCodec:       int32_t channel-count = 2
02-27 16:55:47.571 10131 10219 D MediaCodec:       int32_t sample-rate = 44100
02-27 16:55:47.571 10131 10219 D MediaCodec:       int32_t channel-mask = 0
02-27 16:55:47.571 10131 10219 D MediaCodec:       int32_t pcm-encoding = 2
02-27 16:55:47.571 10131 10219 D MediaCodec:     }
02-27 16:55:47.573 10131 10219 I MediaCodec: (0x96cdbe00) start
02-27 16:55:47.580 10131 10383 I MediaCodec: (0x96cdbe00) input buffers allocated
02-27 16:55:47.580 10131 10383 I MediaCodec: (0x96cdbe00) numBuffers (4)
02-27 16:55:47.581 10131 10383 I MediaCodec: (0x96cdbe00) output buffers allocated
02-27 16:55:47.581 10131 10383 I MediaCodec: (0x96cdbe00) numBuffers (4)
02-27 16:55:47.585 10131 10383 D MediaCodec: (0x96cdbe00) [OMX.google.raw.decoder] output format changed to: AMessage(what = 0x00000000) = {
02-27 16:55:47.585 10131 10383 D MediaCodec:       string mime = "audio/raw"
02-27 16:55:47.585 10131 10383 D MediaCodec:       int32_t channel-count = 2
02-27 16:55:47.585 10131 10383 D MediaCodec:       int32_t sample-rate = 44100
02-27 16:55:47.585 10131 10383 D MediaCodec:       int32_t pcm-encoding = 2
02-27 16:55:47.585 10131 10383 D MediaCodec:       int32_t bit-width = 16
02-27 16:55:47.585 10131 10383 D MediaCodec:       int32_t channel-mask = 0
02-27 16:55:47.585 10131 10383 D MediaCodec:     }
02-27 16:55:47.606 10131 10219 I MediaCodec: (0x96cdbe00) stop
02-27 16:55:47.612 10131 10219 I MediaCodec: (0x96cdbe00) release
02-27 16:55:47.616 10131 10154 D SoundPlayer: onLoadComplete(samp=4|ms=1044, samp=4)=0
02-27 16:55:47.618 10131 10220 W AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by client; transfer 4, track 44100 Hz, output 48000 Hz
02-27 16:55:47.623 10131 10220 D SoundPlayer: playing volume=1.000000 samp=4|ms=1044
02-27 16:55:47.641 10131 10216 V Robocol : sending CMD_PLAY_SOUND(12862), attempt: 0
02-27 16:55:48.522 10131 10131 V FtDeviceManager: ACTION_USB_DEVICE_DETACHED: /dev/bus/usb/001/006
02-27 16:55:49.376 10131 10131 V FtDeviceManager: ACTION_USB_DEVICE_ATTACHED: /dev/bus/usb/001/007
02-27 16:55:49.376 10131 10131 V FtDeviceManager: addOrUpdateUsbDevice(vid=0x0403 pid=0x6015)
02-27 16:55:49.377 10131 10131 V FtDeviceManager: requesting permissions for device=/dev/bus/usb/001/007
02-27 16:55:49.405 10131 10131 V FtDevice: initialize(vid=0x0403 pid=0x6015 bcdDevice=0x1000)
02-27 16:55:49.405 10131 10131 V MonitoredUsbDeviceConnection: closing UsbDeviceConnection(DQ15NX6V)
02-27 16:55:49.405 10131 10131 D UsbDeviceConnectionJNI: close
02-27 16:55:49.406 10131 10131 V MonitoredUsbDeviceConnection: closing UsbDeviceConnection(DQ15NX6V)
02-27 16:55:49.406 10131 10131 D UsbDeviceConnectionJNI: close
02-27 16:55:49.406 10131 10131 V RCActivity: onPause()
02-27 16:55:49.420 10131 10131 V RCActivity: ACTION_USB_DEVICE_ATTACHED: /dev/bus/usb/001/007
02-27 16:55:49.421 10131 10229 I FtcEventLoop: vv===== MODULE ATTACH: disarm REV Robotics USB Expansion Hub Portal [DQ15NX6V]=====vv
02-27 16:55:49.421 10131 10131 V RCActivity: onResume()
02-27 16:55:49.421 10131 10229 V LynxUsb : disarmDevice() serial=DQ15NX6V...
02-27 16:55:49.422 10131 10229 V LynxUsb : ...done disarmDevice()
02-27 16:55:49.423 10131 10229 I FtcEventLoop: ======= MODULE ATTACH: arm or pretend REV Robotics USB Expansion Hub Portal [DQ15NX6V]=======
02-27 16:55:49.423 10131 10374 V RobotCore: thread: ...terminating 'LinearOpMode main'
02-27 16:55:49.426 10131 10229 V FtDeviceManager: createDeviceInfoList(): 1 USB devices
02-27 16:55:49.428 10131 10211 D RobotCore: system telemetry: key=$System$None$ msg=""
02-27 16:55:49.431 10131 10229 V FtDevice: vv********************DQ15NX6V opening********************vv 0x07f962de
02-27 16:55:49.432 10131 10229 V FtDevice: ^^********************DQ15NX6V opened ********************^^
02-27 16:55:49.432 10131 10229 V FtDevice: resetting DQ15NX6V
02-27 16:55:49.443 10131 10229 V LynxUsb : armDevice() serial=DQ15NX6V...
02-27 16:55:49.446 10131 10229 V LynxModule: pingAndQueryKnownInterfaces mod=3
02-27 16:55:49.447 10131 10413 V RobotCore: thread: 'lynx incoming datagrams' starting...
02-27 16:55:49.449 10131 10413 V LynxUsb : synchronization gained: serial=DQ15NX6V
02-27 16:55:49.452 10131 10229 V LynxModule: mod#=3 queryInterface(DEKA)=54 commands starting at 4096
02-27 16:55:49.469 10131 10229 V LynxModule: sendLEDPatternSteps(): #steps=8
02-27 16:55:49.471 10131 10217 V LynxModule: received status: LynxGetModuleStatusResponse(status=0x05 alerts=0x00: KeepAliveTimeout|FailSafe)
02-27 16:55:49.471 10131 10217 V LynxModule: resendCurrentPattern()
02-27 16:55:49.471 10131 10217 V LynxModule: sendLEDPatternSteps(): #steps=8
02-27 16:55:49.485 10131 10229 V LynxModule: pingAndQueryKnownInterfaces mod=4
02-27 16:55:49.493 10131 10229 V LynxModule: mod#=4 queryInterface(DEKA)=54 commands starting at 4096
02-27 16:55:49.509 10131 10229 V LynxModule: sendLEDPatternSteps(): #steps=10
02-27 16:55:49.513 10131 10223 V LynxModule: received status: LynxGetModuleStatusResponse(status=0x05 alerts=0x00: KeepAliveTimeout|FailSafe)
02-27 16:55:49.513 10131 10223 V LynxModule: resendCurrentPattern()
02-27 16:55:49.513 10131 10223 V LynxModule: sendLEDPatternSteps(): #steps=10
02-27 16:55:49.534 10131 10229 V LynxUsb : ...done armDevice()
02-27 16:55:49.535 10131 10229 I FtcEventLoop: ^^===== MODULE ATTACH: complete REV Robotics USB Expansion Hub Portal [DQ15NX6V]=====^^
02-27 16:55:49.535 10131 10229 E EventLoopManager: Event loop threw an exception
02-27 16:55:49.538 10131 10229 E EventLoopManager: org.openftc.revextensions2.RE2Exception: Failed to reflect on LynxController! This probably means that you're running a newer version of the SDK then I tested with and the Tech Team broke something :(
02-27 16:55:49.539 10131 10229 E EventLoopManager: 	at org.openftc.revextensions2.OpenLynxController.<init>(OpenLynxController.java:61)
02-27 16:55:49.539 10131 10229 E EventLoopManager: 	at org.openftc.revextensions2.RevBulkData.validateLynxController(RevBulkData.java:387)
02-27 16:55:49.540 10131 10229 E EventLoopManager: 	at org.openftc.revextensions2.RevBulkData.throwIfMotorInvalid(RevBulkData.java:370)
02-27 16:55:49.541 10131 10229 E EventLoopManager: 	at org.openftc.revextensions2.RevBulkData.getMotorCurrentPosition(RevBulkData.java:123)
02-27 16:55:49.541 10131 10229 E EventLoopManager: 	at org.firstinspires.ftc.teamcode.Hardware_GFORCE.readEncoder(Hardware_GFORCE.java:396)
02-27 16:55:49.542 10131 10229 E EventLoopManager: 	at org.firstinspires.ftc.teamcode.Hardware_GFORCE.getCurrentWristAngle(Hardware_GFORCE.java:986)
02-27 16:55:49.544 10131 10229 E EventLoopManager: 	at org.firstinspires.ftc.teamcode.Hardware_GFORCE.runWristPID(Hardware_GFORCE.java:1018)
02-27 16:55:49.545 10131 10229 E EventLoopManager: 	at org.firstinspires.ftc.teamcode.Hardware_GFORCE.runPIDs(Hardware_GFORCE.java:747)
02-27 16:55:49.546 10131 10229 E EventLoopManager: 	at org.firstinspires.ftc.teamcode.TELEOP.runOpMode(TELEOP.java:143)
02-27 16:55:49.546 10131 10229 E EventLoopManager: 	at com.qualcomm.robotcore.eventloop.opmode.LinearOpMode$LinearOpModeHelper$1.run(LinearOpMode.java:305)
02-27 16:55:49.547 10131 10229 E EventLoopManager: 	at com.qualcomm.robotcore.util.ThreadPool.logThreadLifeCycle(ThreadPool.java:737)
02-27 16:55:49.548 10131 10229 E EventLoopManager: 	at com.qualcomm.robotcore.eventloop.opmode.LinearOpMode$LinearOpModeHelper.run(LinearOpMode.java:300)
02-27 16:55:49.548 10131 10229 E EventLoopManager: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
02-27 16:55:49.549 10131 10229 E EventLoopManager: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
02-27 16:55:49.550 10131 10229 E EventLoopManager: 	at com.qualcomm.robotcore.util.ThreadPool$ThreadFactoryImpl$1.run(ThreadPool.java:793)
02-27 16:55:49.550 10131 10229 E EventLoopManager: 	at java.lang.Thread.run(Thread.java:761)
02-27 16:55:49.551 10131 10229 V RobotCore: RobotCoreException in EventLoopManager: EventLoop Exception in loop(): RE2Exception - Failed to reflect on LynxController! This probably means that you're running a newer version of the SDK then I tested with and the Tech Team broke something :(
02-27 16:55:49.551 10131 10229 V RobotCore: EventLoopManager state is EMERGENCY_STOP
02-27 16:55:49.552 10131 10229 V RobotCore: Robot Status: EMERGENCY STOP
02-27 16:55:49.552 10131 10229 D RobotCore: system telemetry: key=$System$Error$ msg="User code threw an uncaught exception: RE2Exception - Failed to reflect on LynxController! This probably means that you're running a newer version of the SDK then I tested with and the Tech Team broke something :("
02-27 16:55:49.553 10131 10229 I FtcEventLoop: ======= TEARDOWN =======
02

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.