How can i get several values from asynchronous inputs? (object detection & pose detection)

Im going to make some flow that perform operations based on detected objects and motion.

so first of all, I made that the camera input stream is transmitted to the object recognition node and the pose recognition node in parallel.

but the problem is that the following node after two recognition nodes can't get both of output values at the same time because theses outputs are asynchronous

how can i solve this problem?

Welcome to the forum @hero

See this article in the cookbook for an example of how to join messages into one object, which I think it's what you are asking.

1 Like

How about a function node?

[{"id":"77fb6a686686f25e","type":"inject","z":"6f729596a4b72dd6","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"nothing","payloadType":"str","x":350,"y":320,"wires":[["f334b635cf738b20"]]},{"id":"e22b766ad5f30e6c","type":"inject","z":"6f729596a4b72dd6","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"no_pose","payloadType":"str","x":360,"y":500,"wires":[["6fb7c7ef7790601b"]]},{"id":"1ecf48f75f4bc5be","type":"inject","z":"6f729596a4b72dd6","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"cat","payloadType":"str","x":350,"y":360,"wires":[["f334b635cf738b20"]]},{"id":"373979a7e10313aa","type":"inject","z":"6f729596a4b72dd6","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"sitting","payloadType":"str","x":350,"y":540,"wires":[["6fb7c7ef7790601b"]]},{"id":"a85b801b2b94eb9d","type":"inject","z":"6f729596a4b72dd6","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"walking","payloadType":"str","x":350,"y":580,"wires":[["6fb7c7ef7790601b"]]},{"id":"64a0fa709af412fd","type":"inject","z":"6f729596a4b72dd6","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"dog","payloadType":"str","x":350,"y":400,"wires":[["f334b635cf738b20"]]},{"id":"f334b635cf738b20","type":"change","z":"6f729596a4b72dd6","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"object","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":360,"wires":[["7c02427e5ab1352f"]]},{"id":"6fb7c7ef7790601b","type":"change","z":"6f729596a4b72dd6","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"pose","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":540,"wires":[["7c02427e5ab1352f"]]},{"id":"7c02427e5ab1352f","type":"function","z":"6f729596a4b72dd6","name":"","func":"const valOrReset = function (newVal, oldVal, lastVal, resetVal) {\n    return (newVal == oldVal) ? lastVal : resetVal\n}\n\nconst resetObject = 'nothing'\nconst resetPose = 'no_pose'\n\nconst lastObject = flow.get('lastObject') || resetObject\nconst lastPose = flow.get('lastPose') || resetPose\n\nlet newObject\nlet newPose\n\nif (msg.topic == 'object') {\n    newObject = msg.payload\n    flow.set('lastObject', newObject)\n    newPose = valOrReset(newObject, lastObject, lastPose, resetPose)\n} else {\n    if (msg.topic == 'pose') {\n        newPose = msg.payload\n        flow.set('lastPose', newPose)\n        //newObject = valOrReset(newPose, lastPose, lastObject, resetObject)\n        newObject = lastObject\n    } else {\n        msg.payload = { 'object': lastObject, 'pose': lastPose }\n        return msg;\n    }\n\n}\n\nmsg.payload = { 'object': newObject, 'pose': newPose }\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":760,"y":440,"wires":[["cc032979ee6f1822"]]},{"id":"cc032979ee6f1822","type":"debug","z":"6f729596a4b72dd6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":930,"y":440,"wires":[]}]

Gives you in payload an object like this:

EDIT: corrected function to keep old Object if only pose changed

1 Like

Or write zero code and use the join node as @Colin suggested :wink:

[{"id":"77fb6a686686f25e","type":"inject","z":"8fb7704d922a7884","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"nothing","payloadType":"str","x":1094.000087738037,"y":400.0000581741333,"wires":[["f334b635cf738b20"]]},{"id":"e22b766ad5f30e6c","type":"inject","z":"8fb7704d922a7884","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"no_pose","payloadType":"str","x":1104.000087738037,"y":580.0000581741333,"wires":[["6fb7c7ef7790601b"]]},{"id":"1ecf48f75f4bc5be","type":"inject","z":"8fb7704d922a7884","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"cat","payloadType":"str","x":1094.000087738037,"y":440.0000581741333,"wires":[["f334b635cf738b20"]]},{"id":"373979a7e10313aa","type":"inject","z":"8fb7704d922a7884","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"sitting","payloadType":"str","x":1094.000087738037,"y":620.0000581741333,"wires":[["6fb7c7ef7790601b"]]},{"id":"a85b801b2b94eb9d","type":"inject","z":"8fb7704d922a7884","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"walking","payloadType":"str","x":1094.000087738037,"y":660.0000581741333,"wires":[["6fb7c7ef7790601b"]]},{"id":"64a0fa709af412fd","type":"inject","z":"8fb7704d922a7884","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"dog","payloadType":"str","x":1094.000087738037,"y":480.0000581741333,"wires":[["f334b635cf738b20"]]},{"id":"f334b635cf738b20","type":"change","z":"8fb7704d922a7884","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"object","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1284.000087738037,"y":440.0000581741333,"wires":[["e755a445b5658da5"]]},{"id":"6fb7c7ef7790601b","type":"change","z":"8fb7704d922a7884","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"pose","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1284.000087738037,"y":620.0000581741333,"wires":[["e755a445b5658da5"]]},{"id":"cc032979ee6f1822","type":"debug","z":"8fb7704d922a7884","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1630,"y":520,"wires":[]},{"id":"e755a445b5658da5","type":"join","z":"8fb7704d922a7884","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1470,"y":520,"wires":[["cc032979ee6f1822"]]}]
1 Like

Sure, you could. But it behaves slightly different; especially does not reset the pose if object changed.
Guess it depends what the user really needs (?) :slight_smile:

1 Like

in the join node turn off "and every subsequent message" and add a suitable timeout instead such that both messages would arrive within that timeframe.

2 Likes

thanks! for your reply :slight_smile: lol

thanks! for your reply :slight_smile: i also thought about using func but it was hard :slight_smile: