UNPKG

node-red-contrib-seeed-recamera

Version:
191 lines (168 loc) 6.22 kB
<script type="text/html" data-template-name="can-to-angle"> <div class="form-row"> <label for="node-input-name"> <i class="fa fa-tag"></i> <span>Name</span> </label> <input type="text" id="node-input-name" /> </div> <div class="form-row"> <label for="node-input-name"> <i class="fa fa-arrow-circle-right"></i> <span>Input</span> </label> <input type="text" id="node-input-input" /> <input type="hidden" id="node-input-input-type" /> </div> <div class="form-row"> <label style="width: 100%;"> <i class="fa fa-arrow-circle-left"></i> <span>Output as <b>motor angle</b></span> </label> </div> <div class="form-row"> <label for="node-input-unit"> <i class="fa fa-pencil"></i> <span>Unit</span> </label> </div> <div class="form-row"> <div style="margin-left: 10px;"> <div> <div style="display: flex; margin-bottom: 5px;"> <input style="width: auto; margin: 0 10px;" type="radio" name="node-input-unit" id="node-input-unit-decimal" value="0" /> <span>Output in decimal (e.g 180.23 as 180.23 degrees)</span> </div> <div style="display: flex;"> <input style="width: auto; margin: 0 10px;" type="radio" name="node-input-unit" id="node-input-unit-integer" value="1" /> <span>Output in integer (e.g 18023 as 180.23 degrees)</span> </div> </div> </div> </div> </script> <script type="text/javascript"> RED.nodes.registerType("can-to-angle", { category: "reCamera gimbal", color: "#C6D09C", defaults: { name: { value: "" }, input: { value: "payload", required: true }, "input-type": { value: "msg" }, unit: { value: "0" } }, inputs: 1, outputs: 1, icon: "font-awesome/fa-exchange", paletteLabel: "CAN to angle", label: function () { return this.name || "CAN to angle"; }, oneditprepare: function () { const node = this; $("#node-input-input").typedInput({ type: "msg", types: ["msg", "flow", "global"], typeField: "#node-input-input-type", }); $(`input[name="node-input-unit"][value="${node.unit || "0"}"]`).prop("checked", true); }, oneditsave: function () { this.unit = $('input[name="node-input-unit"]:checked').val(); this.input = $("#node-input-input").typedInput("value"); }, }); </script> <script type="text/markdown" data-help-name="can-to-angle"> # CAN to angle This node decodes and converts the raw data read from CANbus to decimal angular values. ## Overview The node takes a CAN message object as input and extracts the motor ID, command type, and angle/offset value. It supports absolute position commands (A4), relative offset commands (A8), and status query commands (94). ## Input Configuration The Input field allows you to specify the message property, flow context, or global context variable that contains the CAN message object. By default, it uses `msg.payload`. ## Input Format The input should be a CAN message object with the following structure: ```json { "id": 0x141, // Motor ID in hex format (0x141 for Yaw, 0x142 for Pitch) "data": [...] // Byte array containing the command data (8 bytes) } ``` Example: ```json { "id": 0x141, "data": [0xA4, 0x00, 0x5A, 0x00, 0x10, 0x27, 0x00, 0x00] } ``` ## Command Validation The node includes advanced validation to ensure only meaningful data commands are processed: - **94 commands**: Must NOT have all remaining bytes as zero (which would indicate a query, not a response) - **A4/A6 commands**: The second byte must be 0x00 or 0x01 to be considered valid (excludes ACK responses like 0x2F) - **A8 commands**: The second byte must be 0x00 to be considered valid These validation rules prevent processing ACK responses and query commands that would result in incorrect angle calculations. ## Unit - **Output in decimal**: Outputs angle values in decimal degrees (e.g., 180.23°) - **Output in integer**: Outputs angle values in integer format representing hundredths of degrees (e.g., 18023 = 180.23°) ## Output The node outputs a JSON object with the decoded information: For absolute position commands (A4) with "Output in decimal" selected: ```json { "payload": { "motorId": 0x141, "angle": 90.5 } } ``` For absolute position commands (A4) with "Output in integer" selected: ```json { "payload": { "motorId": 0x141, "angle": 9050 } } ``` For relative offset commands (A8) with "Output in decimal" selected: ```json { "payload": { "motorId": 0x142, "offset": 5.0 } } ``` For status query commands (94) with "Output in decimal" selected: ```json { "payload": { "motorId": 0x141, "status": true, "angle": 90.5 } } ``` ## Motor IDs - Yaw motor (horizontal): `0x141` - Pitch motor (vertical): `0x142` ## Command Types - `0xA4`: Absolute position command - `0xA8`: Relative offset command - `0x94`: Status query command ## Angle Units - **Raw Value**: Motor units (hundredths of degrees) - **Converted Value**: Degrees ## Notes - The node handles the byte order conversion (little-endian format) - Error messages are displayed if the input format is invalid - When "Output in decimal" is selected, the values are more human-readable - When "Output in integer" is selected, the values match the motor's internal units - Invalid commands and ACK responses are filtered out with a yellow status indicator ## Technical Notes - Motor units are in hundredths of degrees (0.01 degree/LSB) - The raw value is useful for high-precision applications - The converted value is more human-readable - Status commands (94) return the current angle of the motor - ACK responses with second byte 0x2F are automatically filtered </script>