carrot-ar / carrot Goto Github PK
View Code? Open in Web Editor NEW๐ฅ Build multi-device AR applications
License: BSD 3-Clause "New" or "Revised" License
๐ฅ Build multi-device AR applications
License: BSD 3-Clause "New" or "Revised" License
Currently, we are calculating the e_p value when a payload is created in the application layer of carrot as seen here. The issue with this is that if more than two people are connected to the server, then the e_p
value will be invalid since e_p
can only be calculated for the first secondary device
that connects to the server. This results in every client that isn't the first secondary device
to receive the e_p
value for the first secondary device
.
I've been thinking of a few ways to fix this and I'll go through them in order of the most difficult approach to the fastest, simplest approach:
This is the most difficult way to approach this and I've been working on it a bit before the new year in the calc_ep_all_messages
branch. Alas, the break was long and comfortable and I lost track of what I was doing there. In essence, the approach taken was to provide something similar to the Buffalo Context and contain everything related to every request in its own context. This way, we can just call something like calculateE_P()
right before the message is broadcasted. This approach is going to require the most amount of work, but will be the cleanest and should be approached this way eventually.
Almost exactly the same as the above, we could create a factory to build a context but build the context right before control of the request is handed up to the application layer. This will be faster to develop and a good trial to see how it works at the cost of increasing code complexity and is harder to debug.
Right now the e_p is calculated in here like was mentioned above. This happens when the response is built at the application layer here. This begs the question of:
Should the application layer even be building the response? Why should the application layer and developer care about serialized binary data?
To fix this, we could refactor the response building such that it is inaccessible to the developer. As a result, we can store the entire response, unserialized, in the OutMessage
data structure. Doing so allows us to calculate the e_p
value and serialize the response somewhere around here.
This is the simplest and easiest approach at the cost of not solving any of the decoupled response/request issues that would be solved by the first two. Yet, considering that we should try to keep this change as atomic as possible due to the potentially finicky nature of calculating the e_p
value it may be the best for now.
Finally, this bug is blocking the progression of #62 so it is complete more feature dev can take place
Replication: Uncomment the RunTest
and try running go test
/var/folders/h8/3736jd1d7f58wb4xxx0pfwyh0000gn/T/go-build458198568/github.com/carrot-ar/carrot/_test/carrot.test flag redefined: addr
--- FAIL: TestRun (0.00s)
panic: /var/folders/h8/3736jd1d7f58wb4xxx0pfwyh0000gn/T/go-build458198568/github.com/carrot-ar/carrot/_test/carrot.test flag redefined: addr [recovered]
panic: /var/folders/h8/3736jd1d7f58wb4xxx0pfwyh0000gn/T/go-build458198568/github.com/carrot-ar/carrot/_test/carrot.test flag redefined: addr
goroutine 5 [running]:
testing.tRunner.func1(0xc4201040f0)
/usr/local/go/src/testing/testing.go:711 +0x2d2
panic(0x1343200, 0xc420010e40)
/usr/local/go/src/runtime/panic.go:491 +0x283
flag.(*FlagSet).Var(0xc42005c060, 0x1580060, 0xc420010e00, 0x13c6d2b, 0x4, 0x13cbab7, 0x14)
/usr/local/go/src/flag/flag.go:793 +0x5e1
flag.(*FlagSet).StringVar(0xc42005c060, 0xc420010e00, 0x13c6d2b, 0x4, 0xc42001a528, 0x5, 0x13cbab7, 0x14)
/usr/local/go/src/flag/flag.go:696 +0x8b
flag.(*FlagSet).String(0xc42005c060, 0x13c6d2b, 0x4, 0xc42001a528, 0x5, 0x13cbab7, 0x14, 0xc420148000)
/usr/local/go/src/flag/flag.go:709 +0x8b
flag.String(0x13c6d2b, 0x4, 0xc42001a528, 0x5, 0x13cbab7, 0x14, 0x5)
/usr/local/go/src/flag/flag.go:716 +0x69
github.com/carrot-ar/carrot.(*Server).Serve(0xc420076ff0)
/Users/landry/src/github.com/carrot-ar/carrot/server.go:98 +0xc2
github.com/carrot-ar/carrot.Run(0xc420058080, 0xc42002bf98)
/Users/landry/src/github.com/carrot-ar/carrot/app.go:44 +0x4e5
github.com/carrot-ar/carrot.TestRun(0xc4201040f0)
/Users/landry/src/github.com/carrot-ar/carrot/app_test.go:8 +0x22
testing.tRunner(0xc4201040f0, 0x13de098)
/usr/local/go/src/testing/testing.go:746 +0xd0
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:789 +0x2de
exit status 2
FAIL github.com/carrot-ar/carrot 0.016s
Should respond with an error message instead
DEBU[0593] new request module=middleware session_token=e8134530-0dcf-44c2-850f-2c5bc3b20b6a
ERRO[0593] route does not exist
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x1313f39]
goroutine 34 [running]:
github.com/carrot-ar/carrot.(*Dispatcher).dispatchRequest(0xc4200dc4e0, 0x0, 0xc4201ce310, 0x15aff40, 0xc4202d0000)
/Users/landry/src/github.com/carrot-ar/carrot/dispatcher.go:35 +0x49
github.com/carrot-ar/carrot.(*Dispatcher).Run(0xc4200dc4e0)
/Users/landry/src/github.com/carrot-ar/carrot/dispatcher.go:80 +0x4b3
created by github.com/carrot-ar/carrot.(*MiddlewarePipeline).Run
/Users/landry/src/github.com/carrot-ar/carrot/middleware.go:45 +0x43
exit status 2
Messages should now be of the format:
{
"session_token": "E628E5F8-C36C-496A-93FC-0C247A3E6E5F",
"endpoint": "test_endpoint",
"payload": {
"transform": {
"c0": [1, 2, 3, 4],
"c1": [1, 2, 3, 4],
"c2": [1, 2, 3, 4],
"c3": [1, 2, 3, 4]
},
"params": {
"foo": "bar"
}
}
}
The transform
key is a dictionary containing four arrays, one for each column of the matrix. That's to say, the matrix actually looks like:
c0 | c1 | c2 | c3 |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 2 | 2 | 2 |
3 | 3 | 3 | 3 |
4 | 4 | 4 | 4 |
What we're passing around now is a standard 4x4 transformation matrix. We need this in order to maintain other information about the geometry like its rotation and scaling so that other devices can render it properly.
The same 3D point we were dealing with is now in the last (fourth) column of the matrix, except it's now 4D because we're also including w. Example:
c0 | c1 | c2 | c3 |
---|---|---|---|
1 | 0 | 0 | x |
0 | 1 | 0 | y |
0 | 0 | 1 | z |
0 | 0 | 0 | w |
So, in order to do the math you want to be manipulating that last column and preserving w. So, extracting the x, y, and z coordinates would look something like:
let x = matrix[3][0]
let y = matrix[3][1]
let z = matrix[3][2]
From there it's as simple as doing the same math we're already doing and leaving everything else in the matrix exactly as is:
matrix[3][0] = newX
matrix[3][1] = newY
matrix[3][2] = newZ
Happy to help with writing code, reviewing PRs, or anything else I might be able to help with! Let me know if I need to clear anything else up.
Reproduction:
Setup write pump to buffer writes with a delimiter, some of them will send together instead of as individual messages.
Thanks to awesome framework. when I quickly read document I found it carrot can be run on IOS.
Is there any chance to porting to android?
If yes, which notes should be considered?
Thanks
Currently, E_P calculations are only supported for two devices. In order to send responses to more than two devices, distinct calculations must be sent upon individual recipient broadcast. Therefore this issue cannot be completed until issue #66 is addressed.
When broadcasting distinct responses to each recipient becomes possible, the below psuedocode should make sure that the correct event placement is being broadcast to each type of device registered with the server:
when building response messages:
event //unconverted event coordinates that may be recalculated twice depending on a particular broadcast's sender and recipient's roles
var e_l //obtain event in primary device's coordinates (first potential calcuation)
var e_p //obtain event in secondary device's coordinates (second potential calcuation)
if sender is a secondary device { //establish primary perspective
//calculate object in primary device's coordinates
find primary device
e_l = getE_L(sender, primaryDevice, event)
} else { //sender is primary device & already in perspective
e_l = event
}
//transform and/or broadcast primary device's event
for the list of recipient devices
if recipient != primaryDevice && sender != recipient {
e_p = getE_P(recipient, e_l)
//calculate e_p from primary to secondary device
//e_p = e_l - o_p
//where o_p = t_p - t_l
} else { //device == primary device || self to self broadcast
e_p = e_l
}
broadcast e_p as the offset in the response for this recipient device
The existing getE_P function will probably need to be separated into getE_L (get event coordinates local to the primary device) and getE_P (get event coordinates relative to the target device) for the two different stages of calculations as seen above. The beginning work of this can be found in the handle3PlusDevices branch.
Currently, sessions are stored in the application memory. Adding a memcached driver will let developers share sessions across app instances
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.