text:
---
id: openthread-border-router-ipv6-multicast
summary: Thread 1.2 introduces Multicast across Thread Networks, which allows multicast communication between Thread network and Infrastructure (Wi-Fi/ethernet) network segments.  This codelab will guide you through the process to set up and play with Thread 1.2 Multicast features.
status: [final]
authors: Simon Lin
categories: Nest
tags: web
feedback link: https://github.com/openthread/ot-br-posix/issues

---

# Thread Border Router - Thread 1.2 Multicast

[Codelab Feedback](https://github.com/openthread/ot-br-posix/issues)

## Introduction

### **What is Thread?**

Thread is an IP-based low-power wireless mesh networking protocol that enables secure device-to-device and device-to-cloud communications. Thread networks can adapt to topology changes to avoid single-point failures.

> aside positive
>
> Dive Deeper: Refer to  [Thread Overview](https://www.threadgroup.org/What-is-Thread/Overview) for more on Thread.

### **What is OpenThread?**

[OpenThread released by Google](https://github.com/openthread/openthread) is an open-source implementation of Thread®.

### What is an OpenThread Border Router?

[OpenThread Border Router](https://openthread.io/guides/border-router) (OTBR) released by Google is an open-source implementation of the Thread Border Router.

### **Thread 1.2 Multicast**

Thread 1.2 defines a series of features to support multicast across a heterogeneous network (Thread and Wi-Fi/Ethernet Network segments) for multicast addresses with scope larger than realm local.

A Thread 1.2 Border Router registers its Backbone Router (BBR) Dataset, and the selected BBR service is the Primary Backbone Router (PBBR), which is responsible for the multicast inbounding/outbounding forward.

A Thread 1.2 Device sends a CoAP message to register the multicast address to the PBBR (Multicast Listener Registration, MLR for short) if the address is larger than realm local. PBBR uses MLDv2 on its External Interface to communicate to the wider IPv6 LAN/WAN about IPv6 multicast groups it needs to listen to, on behalf of its local Thread Network. And PBBR only forwards multicast traffic into the Thread Network if the destination is subscribed to by at least one Thread device.

For Thread 1.2 Minimal End Devices, they may depend on their parent to aggregate the multicast address and do MLR on their behalf, or register themselves if their parent is of Thread 1.1.

For more details, please refer to **Thread 1.2 Specification Section 5.24 Multicast Forwarding  for larger than Realm-Local Scope**.

### **What you will build**

In this codelab, you're going to set up a Thread Border Router and two Thread devices, then enable and verify Multicast features on Thread devices and Wi-Fi devices.

### **What you will learn**

* How to build nRF52840 firmware with Thread 1.2 Multicast features.
* How to subscribe to IPv6 multicast addresses on Thread devices.

### **What you will need**

* A Raspberry Pi 3/4 device and a SD card with at least 8 GB capability.
* 3 Nordic Semiconductor  [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) boards.
* A Wi-Fi AP without  [IPv6 Router Advertisement Guard](https://tools.ietf.org/html/rfc6105) enabled on the router.
* Linux/macOS Laptop (Raspberry Pi also works) with Python3 installed.

## Setup OTBR
Duration: 05:00

**Follow the**  [**Thread Border Router - Bidirectional IPv6 Connectivity and DNS-Based Service Discovery**](https://openthread.io/codelabs/openthread-border-router#1) **codelab to set up a Thread Border Router on the Raspberry Pi.**

When completed, the Raspberry Pi should have created a working Thread network and be connected to a Wi-Fi network.

OTBR should become the Primary Backbone Router within seconds.

```console
$ sudo ot-ctl bbr state
Primary
Done
$ sudo ot-ctl bbr
BBR Primary:
server16: 0xD800
seqno:    23
delay:    1200 secs
timeout:  3600 secs
Done
```

> aside positive
>
> Dive Deeper:
>
> The BBR dataset shows that the OTBR has become the Primary Backbone Router (PBBR):
>
> * `server16` is the RLOC16 of the PBBR.
> * `seqno` is the randomly generated BBR sequence number. PBBR can change seqno to trigger reregistrations.
> * `delay` is the value of Registration Delay, by which Thread devices should delay before reregistrations.
> * `timeout` is the default duration in seconds for which a Multicast Listener Registration (MLR) remains valid. Thread devices will automatically renew their MLR registrations before expiration if they still subscribe to the multicast address.
>
> Refer to  [OpenThread CLI Reference](https://github.com/openthread/openthread/blob/main/src/cli/README.md#bbr-config-seqno-seqno-delay-delay-timeout-timeout) for more on BBR dataset configuration.

## Build and Flash Thread devices
Duration: 05:00

Build the Thread 1.2 CLI application with Multicast and flash the two nRF52840 DK boards.

### **Build nRF52840 DK firmware**

Follow instructions to clone the project and build nRF52840 firmware.

```console
$ mkdir -p ~/src
$ cd ~/src
$ git clone --recurse-submodules --depth 1 https://github.com/openthread/ot-nrf528xx.git
$ cd ot-nrf528xx/
$ script/build nrf52840 USB_trans -DOT_MLR=ON -DOT_THREAD_VERSION=1.2
$ arm-none-eabi-objcopy -O ihex build/bin/ot-cli-ftd ot-cli-ftd.hex
```

We can find the successfully built HEX firmware at `ot-cli-ftd.hex`.

### **Flash nRF52840 DK firmware**

Flash the firmware onto nRF52840 DK using `nrfjprog`, which is part of the  [nRF Command Line Tools](https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools).

```console
$ nrfjprog -f nrf52 --chiperase --program ot-cli-ftd.hex --reset
```

> aside positive
>
> TIP: Refer to the  [OpenThread on nRF52840 Example](https://github.com/openthread/ot-nrf528xx/blob/main/src/nrf52840/README.md) for more details.

## Attach Thread devices to the Thread network
Duration: 03:00

OTBR has created a Thread network in previous steps. We can now add the nRF52840 DKs to the Thread network:

Get raw Active Dataset from OTBR:

```console
$ sudo ot-ctl dataset active -x
0e080000000000000000000300000b35060004001fffc00208dead00beef00cafe0708fddead00beef00000510e50d3d0931b3430a59c261c684585a07030a4f70656e54687265616401022715041021cf5e5f1d80d2258d5cfd43416525e90c0302a0ff
```

Connect to a nRF52840 DK board:

```console
$ screen /dev/ttyACM0 115200
```

Configure the Active Dataset for the nRF52840 DK:

```console
> dataset set active 0e080000000000000000000300000b35060004001fffc00208dead00beef00cafe0708fddead00beef00000510e50d3d0931b3430a59c261c684585a07030a4f70656e54687265616401022715041021cf5e5f1d80d2258d5cfd43416525e90c0302a0ff
Done
```

Start the Thread stack and wait for a few seconds and verify the device has successfully attached:

```console
> ifconfig up
Done
> thread start
Done
> state
child
```

Repeat the above steps to attach the other nRF52840 DK board to the Thread network.

We have now successfully set up the Thread network with 3 Thread devices: OTBR and two nRF52840 DK boards.

## Setup Wi-Fi Network
Duration: 03:00

Setup the Wi-Fi network on OTBR and the Laptop so that they are connected to the same Wi-Fi AP.

We can use  [raspi-config](https://www.raspberrypi.org/documentation/configuration/raspi-config.md) to setup the Wi-Fi SSID and passphrase on the Raspberry Pi OTBR.

The final network topology is shown below:

> aside positive
>
> NOTE: From this step on, the two nRF52840 DKs are used for different purposes. We refer to one as nRF52840 End Device 1 and the other nRF52840 End Device 2.

## Subscribe to the IPv6 multicast address
Duration: 02:00

> aside positive
>
> NOTE: This codelab uses a IPv6 multicast address of `ff05::abcd`, but any IPv6 multicast address with scope >= `Admin-local scope (4)` will also work.

**Subscribe to ff05::abcd on nRF52840 End Device 1:**

```console
> ipmaddr add ff05::abcd
Done
```

Verify `ff05::abcd` is successfully subscribed:

```console
> ipmaddr
ff33:40:fdde:ad00:beef:0:0:1
ff32:40:fdde:ad00:beef:0:0:1
ff05:0:0:0:0:0:0:abcd            <--- ff05::abcd subscribed
ff02:0:0:0:0:0:0:2
ff03:0:0:0:0:0:0:2
ff02:0:0:0:0:0:0:1
ff03:0:0:0:0:0:0:1
ff03:0:0:0:0:0:0:fc
Done
```

**Subscribe to ff05::abcd on the Laptop:**

We need a Python script `subscribe6.py` to subscribe to a multicast address on the Laptop.

Copy the code below and save it as `subscribe6.py`:

```
import ctypes
import ctypes.util
import socket
import struct
import sys

libc = ctypes.CDLL(ctypes.util.find_library('c'))
ifname, group = sys.argv[1:]
addrinfo = socket.getaddrinfo(group, None)[0]
assert addrinfo[0] == socket.AF_INET6
s = socket.socket(addrinfo[0], socket.SOCK_DGRAM)
group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0])
interface_index = libc.if_nametoindex(ifname.encode('ascii'))
mreq = group_bin + struct.pack('@I', interface_index)
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
print("Subscribed %s on interface %s." % (group, ifname))
input('Press ENTER to quit.')
```

Run `subscribe6.py` to subscribe `ff05::abcd` on the Wi-Fi network interface (e.g. wlan0):

```console
$ sudo python3 subscribe6.py wlan0 ff05::abcd
Subscribed ff05::abcd on interface wlan0.
Press ENTER to quit.
```

> aside positive
>
> NOTE: If you press ENTER, the subscription ends.

The final network topology with multicast subscriptions are shown below:

Now that we have subscribed the IPv6 multicast address on both the nRF52840 End Device 1 in Thread network and the Laptop in the Wi-Fi network, we are going to verify bi-directional IPv6 multicast reachability in the following sections.

## Verify Inbound IPv6 Multicast
Duration: 02:00

Now, we should be able to reach both nRF52840 End Device 1 in the Thread network and the Laptop using IPv6 multicast address `ff05::abcd` from the Wi-Fi network.

**Ping ff05::abcd on OTBR via the Wi-Fi interface:**

```console
$ ping -6 -b -t 5 -I wlan0 ff05::abcd
PING ff05::abcd(ff05::abcd) from 2401:fa00:41:801:83c1:a67:ae22:5346 wlan0: 56 data bytes
64 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=1 ttl=64 time=57.4 ms
64 bytes from 2401:fa00:41:801:8c09:1765:4ba8:48e8: icmp_seq=1 ttl=64 time=84.9 ms (DUP!)
64 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=2 ttl=64 time=54.8 ms
64 bytes from 2401:fa00:41:801:8c09:1765:4ba8:48e8: icmp_seq=2 ttl=64 time=319 ms (DUP!)
64 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=3 ttl=64 time=57.5 ms
64 bytes from 2401:fa00:41:801:8c09:1765:4ba8:48e8: icmp_seq=3 ttl=64 time=239 ms (DUP!)
```

We can see that OTBR can receive two ping replies from both the nRF52840 End Device 1 and the Laptop because they both have subscribed to `ff05::abcd`. This shows that the OTBR can forward the IPv6 Ping Request multicast packets from the Wi-Fi network to the Thread network.

> aside positive
>
> NOTE: We need to use `-t ttl` to set the IP Time to Live, which is 1 by default on Linux, otherwise the multicast ping can not reach nRF52840 End Device 1.

## Verify Outbound IPv6 Multicast
Duration: 02:00

**Ping ff05::abcd on nRF52840 End Device 2:**

```console
$ ping ff05::abcd 100 10 1
108 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=12 hlim=64 time=297ms
108 bytes from 2401:fa00:41:801:64cb:6305:7c3a:d704: icmp_seq=12 hlim=63 time=432ms
108 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=13 hlim=64 time=193ms
108 bytes from 2401:fa00:41:801:64cb:6305:7c3a:d704: icmp_seq=13 hlim=63 time=306ms
108 bytes from fdb5:8d36:6af9:7669:e43b:8e1b:6f2a:b8fa: icmp_seq=14 hlim=64 time=230ms
108 bytes from 2401:fa00:41:801:64cb:6305:7c3a:d704: icmp_seq=14 hlim=63 time=279ms
```

nRF52840 End Device 2 can receive ping replies from both the nRF52840 End Device 1 and the Laptop. This shows that the OTBR can forward the IPv6 Ping Reply multicast packages from the Thread network to the Wi-Fi network.

> aside positive
>
> NOTE: We rely on the OTBR Border Routing to forward unicast ping replies.

## Congratulations
Duration: 01:00

Congratulations, you've successfully set up a Thread Border Router and verified bi-directional IPv6 multicast!

For more on OpenThread, visit  [openthread.io](https://openthread.io/).

Reference docs:

*  [Thread Border Router - Bidirectional IPv6 Connectivity and DNS-Based Service Discovery](https://docs.google.com/document/d/1M5o-u9PK3z8P2a4W2qJl7ueFS-KJnfkRwWzT5nPEiAc/edit?resourcekey=0-VSLF6zxOJc-71hov962NWw#heading=h.8s8krlrp7f4l)
*  [Thread Primer](https://openthread.io/guides/thread-primer)
*  [OpenThread Guide](https://openthread.io/guides)
*  [OpenThread CLI Reference](https://github.com/openthread/openthread/blob/main/src/cli/README.md#openthread-cli-reference)

## License

Copyright (c) 2021, The OpenThread Authors.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the
   names of its contributors may be used to endorse or promote products
   derived from this software without specific prior written permission.


text:
# ⚡README Professional Writter⚡

  ![Github License](https://img.shields.io/badge/license-MIT-blue.svg)

  ## Description
  A helpfull application that helps you write README.md files quick and in a professional way

  <ur>

  ## 📋Table of Contents

  [Installation](#installation)

  [Usage](#usage)

[License](#license)

  [Contributing](#contributing)

  [Test](#test)

  [Questions](#questions)

  ## 💾Installation
  npm install....node index.js

  <ur>

  ## 💻 Usage
  this applications will help you write readme files faster
  ## License
    This project is licensed with MIT.

  <ur>

  ## 👪 Contributing

  Julian P

  <ur>

  ## ✏ Test
  npm test
  <ur>

  ## ✋ Questions
  Any questions? Contact<EMAIL_ADDRESS>Access more of my work at [pedrazajulian](https://github.com/pedrazajulian/).

 ![demo](https://media.giphy.com/media/pXCjE1iPeP9mCJOFeq/giphy.gif)

license: MIT

repository: pedrazajulian/ReadmeGen

branch_name: refs/heads/main

extension: md

license_type: permissive

repo_name: pedrazajulian/ReadmeGen


text:
Currently only tested on Ubuntu

Recommend using ```rbenv``` to manage ruby versions.

Make sure dependencies are installed:

```
sudo apt install libusb-1.0-0-dev
gem isntall libusb
```

This command will automatically recognize our production devices and map them to the correct /dev/tty ports:

```
ruby run.rb
```

repository: nathandao/blackjack

branch_name: refs/heads/master

repo_name: nathandao/blackjack


text:
---
layout: post
title: "Weekly Roundup"
permalink: "weekly-roundup-03-02-2018"
date: 2018-03-02
categories: links
summary: Cool front end development links for the week ended 3/2/18.
tags: [front end development, html, css, javascript, links]
---

Welcome once again to the weekly roundup!

Happy Friday! I hope your week has gone well. As usual, I've done a lot of reading and learning this week, and saved some links to the best things I came across so that I can share them with you.  If you're ready to take that a step farther (like I am), here's ten cool examples of cool things people have done with the technology. Best of all, they're in CodePen, so you can play around with them!

[10 Handy CSS Grid Code Snippets](https://speckyboy.com/10-handy-css-grid-code-snippets/)

2. It seems with each new day there's a new technology emerging that's supposed to make our jobs as developers easier, but often results in the opposite. Yes, we have more power at our fingertips and can therefore achieve more, but at a cost of greater complexity. Chris Coyier, founder of CSS-Tricks, opines about what it all means in this esssay.

[On Complexity](https://css-tricks.com/complexity/#more-266794)

3. As developers, we've probably all used CSS resets in our CSS files before. They're the snippets that attempt to neutralize the styles imposed by each individual flavor of browser in an attempt to make our applications render the way we intend them to across all platforms. One of the most popular of those the past few years has been Normalize. Now Sindre Sorhus, an open source developer, has sought to improve on that, by releasing modern-normalize.

 What if I told you a powerful Mac web development environment can be yours with a single terminal command? Check out laptop, from Thoughtbot:

[Laptop](https://github.com/thoughtbot/laptop)

5. Getting your first job as a junior-level developer can be daunting, and even seem impossible at times. There are tons of development job postings all over the internet, but very few for junior devs. What does it mean? At Medium, Melissa McEwen explains why it's a sign the industry is broken.

[Who Killed the Junior Developer?](https://medium.com/@melissamcewen/who-killed-the-junior-developer-33e9da2dc58c)

repository: bpcoxjr/display-blog

extension: markdown

repo_name: bpcoxjr/display-blog


text:
# Qt Frameless Window with DarkStyle
simple MainWindow class implementation with frameless window and custom dark style.

It adds also support for titlebar and buttons (minimize, maximize, close)

Look is based on the VS2013 application window (flat and frameless window)

Screenshots

mac enabled	mac disabled

## Qt and OS
* tested with Qt5.5.0 and Qt5.9.0
* tested on Windows7 and MacOSX 10.12.5

## How to use
* edit mainwindow.cpp/.h
* add your custom QMainWindow code into the class **MainWindow**
* the class **BorderlessMainWindow** is just to add frameless window support and styling
* to use the dark style, add ``#include "DarkStyle.h"`` insto **main.cpp** and call ``CDarkStyle::assign();``
```qt
#include "mainwindow.h"
#include <QApplication>
#include <QPalette>

#include "DarkStyle.h"

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);

  // apply dark style
  CDarkStyle::assign();

  // create and show frameless window
  BorderlessMainWindow w;
  w.show();

  return a.exec();
}
```

## features
* frameless window
* custom dark style (based on **Fusion style** with dark palette and custom stylesheets)
* title bar
* buttons (minimize | restore | maximize | close)
* move window by drag the title bar
* dobule click title bar to toggle between window styte (maximize and normal)

## Licence
> The MIT License
>
> Copyright (c) 2017, Juergen Skrotzky (https://github.com/Jorgen-VikingGod<EMAIL_ADDRESS>>
> 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.

repository: QtLab/Qt-Frameless-Window-DarkStyle

repo_name: QtLab/Qt-Frameless-Window-DarkStyle


text:
# Changelog

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [1.0.0](https://github.com/typeskill/typeskill/compare/v0.11.0-alpha.0...v1.0.0) (2020-02-19)

### Bug Fixes

* **package:** update ramda to version 0.27.0 ([b80ef9a](https://github.com/typeskill/typeskill/commit/b80ef9a))
* unexhaustive hook dependency ([c1ae14d](https://github.com/typeskill/typeskill/commit/c1ae14d))

### Features

* add useDocument and useBridge hooks ([0e96b53](https://github.com/typeskill/typeskill/commit/0e96b53))

## [0.11.0-alpha.0](https://github.com/typeskill/typeskill/compare/v0.10.0-beta.19...v0.11.0-alpha.0) (2019-10-04)

### ⚠ BREAKING CHANGES

* removed `disableMultipleAttributeEdits` Typer prop.
Since this behavior has been proven default on iOS, Typeskill will try
to enforce the same one on Android by default. To make the API more
explicit, it has been found best to rename the prop to narrow the scope
to Android.

### Bug Fixes

* add missing hook dependency ([fa84b1c](https://github.com/typeskill/typeskill/commit/fa84b1c))
* overriding selection iOS doesn't work ([8f38a0b](https://github.com/typeskill/typeskill/commit/8f38a0b))

### Features

* add `androidDisableMultipleAttributeEdits` Typer prop ([348eecb](https://github.com/typeskill/typeskill/commit/348eecb))

repository: decisionnguyen/typer

repo_name: decisionnguyen/typer


text:
### First Assembly Language Program
> Use the code above in your asm_main.asm between the BEGIN CUT and END CUT (don't include those statements) and then, change the hello string to print out your name. Make the main executable by typing make

Due: Wednesday, 18 September 2019, 8:00 AM

license: Unlicense

path: /1. First Program/README.md


text:
# OAuthScreen

OAuthScreen is a sample application used to test OAuth2 in different  API Management products. This first version only support Authorization code grant type.

## Installation

Just install nodejs and clone this proyect in your local machine.

```nodejs
npm install
```

## Usage

```nodejs
node MainApp.js
```
## Access

```nodejs
https://localhost:8089/oauth-form.html
```
## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

## License
[MIT](https://choosealicense.com/licenses/mit/)


text:
# GillespiePy

This *was* originally just a fork of StochPy, with the goal of improving performance. However the StochPy code base is almost unsalvageable, so it has been rewritten from scratch.

GillespiePy is a Python library for simulating stochastic systems. Currently it is simply an implementation of the Gillespie algorithm [[Gillespie 1977](http://pubs.acs.org/doi/abs/10.1021/j100540a008)]. There are plans to expand to more modern implementations of the same algorithm.

## Performance
The Gillespie algorithm is relatively slow, and Python isn't exactly known for performance. To get around this I have done some *extremely* hacky things involving Numba and run time code generation. This does lead to significant performance increases, but Here Be Dirty Code.

## Algorithms

### Implemented
* Direct stochastic simulation, [Gillespie 1977](http://pubs.acs.org/doi/abs/10.1021/j100540a008)

### Planned
* Next reaction [Gibson et al 2000](http://pubs.acs.org/doi/abs/10.1021/jp993732q)
* Delayed next reaction [Anderson 2007](https://arxiv.org/abs/0708.0370)
* Tau leaping? It isn't exact which is kind of a problem.
* GPU support? [Komarov et al 2012](http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0046693)
* Non Markovian processes? [Boguna et al 2013](https://arxiv.org/abs/1310.0926)

repository: vluzko/GillespiePy

repo_name: vluzko/GillespiePy


text:
# UnrealStereo

[UnrealStereo](https://stereo.unrealcv.org/) is a project for generating images from virtual worlds for stereo vision. It is based on [UnrealCV](http://unrealcv.github.io/) which is an open source software connecting Computer Vision to Unreal Engine.

This repository contains codes and data for reproducing the results in our paper.

## Getting Started

### Prerequisites

- Ubuntu
- Python 3

    ```shell
    pip install -r requirements.txt
    ```
- Csh (To run the ELAS algorithm)

    ```shell
    sudo apt-get install csh
    ```

### Installation

1. Clone the repository.

    ```shell
    git clone https://github.com/edz-o/minimum_evaluation.git
    ```
    We'll call the directory that you cloned UnrealStereo into `$ROOT`

### Config ELAS algorithm

1. We are using the implementation from [Middlebury website](http://vision.middlebury.edu/stereo/submit3/).

    ```shell
    wget http://vision.middlebury.edu/stereo/submit3/zip/MiddEval3-SDK-1.6.zip
    unzip MiddEval3-SDK-1.6.zip
    cd MiddEval3
    ```

2. Compile Libelas as follows:

    ```shell
    cd alg-ELAS/build
    cmake ..
    make
    cd ../..
    ```

3. Compile the tools in code/ as follows:

    ```shell
    cd code/imageLib
    make
    cd ..
    make
    cd ..
    ```

4. Copy our python wrapper for the algorithm to `MiddEval3/alg-ELAS`.

    ```shell
    cd $ROOT
    cp run_ELAS.py MiddEval3/alg-ELAS
    ```

### Download unrealstereo data

Download the data we used as follows,

```shell
wget https://cs.jhu.edu/~yzh/unrealstereo_data_hazardous.zip
unzip unrealstereo_data_hazardous.zip
```

The 10k synthetic sequences can be downloaded from [here](https://cs.jhu.edu/~yzh/unrealstereo_10k.zip).

### Reproduce the result

```shell
sh run_all.sh
```
## Annotation of hazardous regions on Middlebury and KITTI 2015

The annotations used in our paper can be downloaded [here](https://cs.jhu.edu/~yzh/kitti15_mb.zip).

## License and Citation

This project is licensed under the MIT License - see the LICENSE file for details.

If you find UnrealStereo useful in your research, please consider citing:

    @inproceedings{zhang2018unrealstereo,
      title={Unrealstereo: Controlling hazardous factors to analyze stereo vision},
      author={Zhang, Yi and Qiu, Weichao and Chen, Qi and Hu, Xiaolin and Yuille, Alan},
      booktitle={2018 International Conference on 3D Vision (3DV)},
      pages={228--237},
      year={2018},
      organization={IEEE}
    }

repository: leonzfa/unreal-stereo-evaluation

repo_name: leonzfa/unreal-stereo-evaluation


text:
# FizzBuzz

Fizz buzz is a group word game for children to teach them about division.
Players take turns to count incrementally, replacing any number divisible by three with the word "fizz", and any number divisible by five with the word "buzz".
[wiki](https://en.wikipedia.org/wiki/Fizz_buzz)

## Implementation

An example implementation has been written using **ES6/TypeScript** (fizzbuzz.ts).

There is also a version in **ES5/JavaScript** (fizzbuzz.js).

## Solutions

Everything starts with the `initialize()` function, which takes a range and a configs array;

A config object has 2 fields:
 * Number - if index modulo this number equals 0, then the comparer method attaches a 'word' to the result
 * Word - wor that is added if the condition above is fulfilled.

repository: Humberd/FizzBuzz

gha_language: JavaScript

repo_name: Humberd/FizzBuzz


text:
## Game socket
The library was published in early access and is not stable, as it is being developed in parallel with other solutions. English is not a native language so there are no comments. At this stage, the library is for those who want to understand the source code and get a starting point for their solution or help me :)

## Features
* One library contains both Server and Client parts.
* The API communication library is similar to `Socket.io`, but not compatible with this solution.
* Contains a built-in binary protocol so you don't have to work at the byte level.
* The transport layer uses `TCP`. To send game messages, it is planned to implement parallel work with `UDP`.
* It implements such concepts as Multiplexing - interaction with several spaces through a single channel.

Support for `WebSocket` is not planned for the current day (but everything can change with the support of the community)

## Example
Examples:
* [`example/client/main.dart`](https://github.com/QiXi/game_socket/blob/master/example/client/main.dart)
* [`example/server/main.dart`](https://github.com/QiXi/game_socket/blob/master/example/server/main.dart)

## Usage
Create client:

```dart
import 'package:game_socket/client.dart';

void main() {
  var client = GameClientExample();
  client.connect('localhost', 3103);
}

class GameClientExample extends GameSocketClient {
  GameClientExample() {
    on(Event.handshake, (packet) => _onHandshake(packet));
    on(Event.roomPacket, (packet) => _onRoomPacket(packet));
  }

  void _onHandshake(Packet packet) {
    if (packet.namespace == '/') {
      sendMessage(ConnectRequest('/home'));
    } else if (packet.namespace == '/home') {
      sendMessage(JoinRoomRequest('lobby', namespace: '/home'));
    }
  }

  void _onRoomPacket(RoomPacket packet) {
    var roomName = packet.roomName;
    if (packet.joinRoom && roomName == 'lobby') {
      var msg = RoomEvent(roomName!, namespace: '/home', event: 'hello', message: 'hello all');
      sendMessage(msg);
    }
  }
}
```
This client connects to the main `/` namespace on the server, then to the `/home` namespace. Then it sends a request to enter the `lobby` room, after which it dispatches a `hello` event containing the message text `hello all`.

Create server:

```dart
import 'package:game_socket/server.dart';

void main() {
  var service = SocketServiceExample();
  service.listen();
}

class SocketServiceExample {
  late GameSocketServer server;
  late Namespace home;

  SocketServiceExample() {
    server = GameSocketServer(options: ServerOptions.byDefault()..supportRawData = true);
    home = server.of('/home');
    home.on(ServerEvent.connect, (data) => _onHomeConnect(data));
    home.on('hello', (packet) => _onHomeData(packet));
    //
    server.on(ServerEvent.connection, (socket) {
      print('/: connection $socket');
      socket.on(ServerEvent.connect, (data) => _onConnect(data[0], data[1]));
      socket.on(Event.disconnecting, (data) => _onDisconnecting(data));
      socket.on(Event.disconnect, (data) => _onDisconnect(data[0], data[1]));
      socket.on(Event.error, (data) => _onError(data));
      socket.on(Event.data, (data) => _onData(data));
      socket.on(Event.close, (data) => {_onClose(data)});
    });
    server.on(ServerEvent.error, (data) => {print('/: eventError $data')});
    server.on(ServerEvent.close, (data) => {print('/: serverClose $data')});
    server.on(ServerEvent.raw, (data) => {print('/: raw $data')});
    server.on(ServerEvent.createRoom, (data) => {print('/: createRoom $data')});
    server.on(ServerEvent.joinRoom, (data) => {print('/: joinRoom $data')});
    server.on(ServerEvent.leaveRoom, (data) => {print('/: leaveRoom $data')});
    server.on(ServerEvent.deleteRoom, (data) => {print('/: deleteRoom $data')});
  }

  void listen() {
    server.listen();
  }

  void _onHomeConnect(dynamic data) {
    print('/home: connect $data');
  }

  void _onHomeData(dynamic data) {
    print('/home: $data');
    if (data is RoomPacket && data.roomName != null) {
      home.broadcast(data, rooms: {data.roomName!});
    }
  }

  void _onConnect(String namespace, String socketId) {
    print('/: connect $socketId');
  }

  void _onDisconnecting(dynamic data) {
    print('/: disconnecting $data');
  }

  void _onDisconnect(String namespace, String reason) {
    print('$namespace: disconnect reason:$reason');
  }

  void _onError(dynamic data) {
    print('/: error $data');
  }

  void _onData(dynamic data) {
    print('/: $data');
  }

  void _onClose(dynamic data) {
    print('/: close $data');
  }
}

```

###### Server log
```
listen null Options{ port:3103 raw:true closeOnError:false }
/: connection GameClient{ 15466abe2006464e99b6c8b36f7f4ed8 ReadyState.open [137545126]}
/: createRoom 15466abe2006464e99b6c8b36f7f4ed8
/: joinRoom [15466abe2006464e99b6c8b36f7f4ed8, 15466abe2006464e99b6c8b36f7f4ed8]
Home: connect [/home, 15466abe2006464e99b6c8b36f7f4ed8]
```

###### Client log
```
open InternetAddress('<IP_ADDRESS>', IPv4) ReadyState.open
handshake Packet{[0.0 /], bit:516, bool:16, int:[0, 0, 60, 0, 0, 0], string:{3: 15466abe2006464e99b6c8b36f7f4ed8}}
>> Message{[/home] boolMask:4, int:[0, 0, 0, 0, 0, 0], string:{} null}
handshake Packet{[0.0 /home], bit:516, bool:16, int:[0, 0, 60, 0, 0, 0], string:{3: 15466abe2006464e99b6c8b36f7f4ed8}}
>> Message{[/home] boolMask:16, int:[0, 0, 0], string:{0: lobby} null}
>> Message{[/home] boolMask:512, int:[0, 0, 0], string:{0: lobby, 5: hello, 1: hello all} null}
```

## Protocol

The protocol is schematic based. This approach allows you to save the amount of data transferred, since the data type is not transferred with the message, and the length of the numbers is not serialized.

Data types used in the schema

| Type | Size | Range |
| ---- | ---- | ----- |
| bool | 1 bit | true or false |
| int8 | 1 byte | 0 to 255 |
| int16 | 2 bytes | 0 to 65535 |
| int32 | 4 bytes | 0 to<PHONE_NUMBER> |
| string | 1 + value | 0 to 255 chars |
| bytes | 2 + value | 0 to 65535 bytes |

Schema creation
```dart
import 'package:game_socket/protocol.dart';
typedef PS = PlayerStateSchema;
class PlayerStateSchema extends SimpleSchema {
  @override
  int get code => 10; // unique schema code 10..255
  @override
  int get version => 1; // version 0..255 to support game clients with different versions

  // bool
  static const int reserved = 0; // reserved
  @override
  int get boolCount => 1;

  // int8
  static const int speed = 0; // 0.000..1.000
  static const int health = 1; // max(100)
  @override
  int get int8Count => 2;
  // int16
  static const int uid = 2; // max(65535)
  static const int angle = 3; // radians
  static const int score = 4; // max(65535)
  @override
  int get int16Count => 3;
  // int32
  static const int elapsedTime = 5; // time for internal synchronization
  static const int x = 6; // x-coordinate
  static const int y = 7; // y-coordinate
  @override
  int get int32Count => 3;

  // strings
  static const int name = 0; // player name
  @override
  int get stringsCount => 1;
}
```
When you create a schema, you do two things: you take the named cell number of the array and determine the length of the array to one of the five schema data types.

Creating a message class
```dart
class PlayerStateMessage extends Message {
  PlayerStateMessage(Player player, {required double elapsedTime}) : super(PS()) {
    putUInt(PS.uid, player.uid);
    putInt(PS.x, (player.positionBody.x * 1000).toInt()); // ~ -2000000.0000..+2000000.0000
    putInt(PS.y, (player.positionBody.y * 1000).toInt());
    putInt(PS.score, player.score);
    putSingle(PS.speed, player.speed);
    putRadians(PS.angle, player.rotationBody);
    putUInt(PS.elapsedTime, (elapsedTime * 1000).toInt()); // double ms
  }
}
```

Data types when writing or reading messages

| Operation | Schema Type | Dart Type | Range |
| --------- | ----------- | --------- | ----- |
| putBool   | bool   | bool| true or false |
| putInt    | int8   | int | -128 to 127 |
| putUInt   | int8   | int | 0 to 255 |
| putInt    | int16  | int | -32768 to 32767 |
| putUInt   | int16  | int | 0 to 65535 |
| putInt    | int32  | int | -2147483648 to<PHONE_NUMBER> |
| putUInt   | int32  | int | 0 to<PHONE_NUMBER> |
| putString | string | String | 0 to 255 chars |
| putSingle | ~int8~ | double | 0 to 1 step ~0.004 |
| putRadians | ~int16~ | double | step ~0.0002 |
| putPayload | bytes | Uint8List | 0 to 65535 bytes |

## Plans
* Initialization for sending `UPD` diagrams.
* Automatic connections and reconnections.
* Expanding the possibilities for working with rooms.
* Conducting stress tests.

## Tips for Beginners
* If you are developing a browser game, then you need a `WebSocket` solution.
* When designing a game for real-time communication, `UDP` should be preferred, since` TCP` will cause a delay in the event of packet loss.

## History of creation
Sources that could have influenced the development of this work:

* https://jamesslocum.com/blog
* https://github.com/socketio/engine.io-server-java
* https://github.com/socketio/socket.io-server-java/
* https://github.com/Jerenaux/binary-protocol-example
* https://github.com/rikulo/socket.io-dart/

___
If you can suggest a translation better than automatic ᕙ(☉̃ₒ☉‶)ว just do it