Device Rotation Control (for System Applications Only)
Mechanic Kit is supported since API version 20, providing a richer photography experience, such as device rotation control (only for system apps).
Using a mobile phone as the control terminal, you can adjust the angle and motion trajectory of mechanic devices like gimbals or robotic arms through precise parameter settings, facilitating the rapid development of mechanic device control applications.
Available APIs
For details about how to use the public APIs of Mechanic Manager, see @ohos.distributedHardware.mechanicManager (Mechanic Manager).
For details about how to use the system APIs of Mechanic Manager, see @ohos.distributedHardware.mechanicManager (Mechanic Manager) (System API).
| Name | Description |
|---|---|
| on(type: 'attachStateChange', callback: Callback<AttachStateChangeInfo>): void | Registers the callback listener for attachStateChange events. Note: This API is supported since API version 20. |
| off(type: 'attachStateChange', callback?: Callback<AttachStateChangeInfo>): void | Unregisters the callback listener for attachStateChange events. Note: This API is supported since API version 20. |
| getAttachedMechDevices(): MechInfo[] | Obtain the list of connected mechanic devices. Note: This API is supported since API version 20. |
| setUserOperation(operation: Operation, mac: string, params: string): void | Sets a user operation. Note: This API is supported since API version 20. |
| setCameraTrackingEnabled(isEnabled: boolean): void | Enables or disables camera tracking. Note: This API is supported since API version 20. |
| getCameraTrackingEnabled(): boolean | Checks whether camera tracking is enabled. Note: This API is supported since API version 20. |
| getCameraTrackingLayout(): CameraTrackingLayout | Obtains the camera tracking layout of the mechanic device. Note: This API is supported since API version 20. |
| rotate(mechId: number, angles: RotationAngles, duration: number): Promise<Result> | Rotates a mechanic device to the relative angles. Note: This API is supported since API version 20. |
| rotateToEulerAngles(mechId: number, angles: EulerAngles, duration: number): Promise<Result> | Rotates a mechanic device to the absolute angles. Note: This API is supported since API version 20. |
| getMaxRotationTime(mechId: number): number | Obtains the maximum duration for continuous rotation of a mechanic device. Note: This API is supported since API version 20. |
| getMaxRotationSpeed(mechId: number): RotationSpeed | Obtains the maximum rotation speed of a mechanic device. Note: This API is supported since API version 20. |
| stopMoving(mechId: number): Promise<void> | Stops movement of a mechanic device. Note: This API is supported since API version 20. |
| getCurrentAngles(mechId: number): EulerAngles | Obtains the current angles of a mechanic device. Note: This API is supported since API version 20. |
| getRotationLimits(mechId: number): RotationLimits | Obtains the maximum rotation angle of a mechanic device relative to the reference point. Note: This API is supported since API version 20. |
| getRotationAxesStatus(mechId: number): RotationAxesStatus | Obtains the status of the rotation axis. Note: This API is supported since API version 20. |
| on(type: 'rotationAxesStatusChange', callback: Callback<RotationAxesStateChangeInfo>): void | Registers a callback listener for the rotationAxesStatusChange events. Note: This API is supported since API version 20. |
| off(type: 'rotationAxesStatusChange', callback?: Callback<RotationAxesStateChangeInfo>): void | Unregisters the callback listener for rotationAxesStatusChange events. Note: This API is supported since API version 20. |
How to Develop
Getting Started
- Prepare a mechanic device that supports Mechanic Kit.
- To verify the intelligent camera tracking function, check that the camera driver of the main device supports face detection.
- Update the SDK to API version 20 or later. For details, see https://developer.huawei.com/consumer/en/doc/harmonyos-guides/ide-software-install.
- Connect the mechanic device to the control device through Bluetooth.
Managing the Device Connection Status
Device connection status management helps to ensure that the application responds promptly when the mechanic device is connected or disconnected.
-
Import the mechanicManager module.
import { mechanicManager } from '@kit.MechanicKit'; -
Obtain the list of connected mechanic devices.
let savedMechanicIds: number[] = []; try { const devices = mechanicManager.getAttachedMechDevices(); console.info('Connected devices:', devices); devices.forEach(device => { console.info(`Device ID: ${device.mechId}`); console.info(`Device Name: ${device.mechName}`); console.info(`Device Type: ${device.mechDeviceType}`); // Save the MechId of the device whose device type is GIMBAL_DEVICE. if (device.mechDeviceType === mechanicManager.MechDeviceType.GIMBAL_DEVICE) { savedMechanicIds.push(device.mechId); console.info(`GIMBAL_TYPE device saved ID: ${device.mechId}`); } else { console.info(`Skip non-gimbal devices: ${device.mechId}`); } }); console.info('List of saved gimbal device IDs:', savedMechanicIds); } catch (err) { console.error('Error getting attached devices:', err); } -
Listen for the connection state changes of the device.
const attachStateChangeCallback = (info: mechanicManager.AttachStateChangeInfo) => { if (info.state === mechanicManager.AttachState.ATTACHED) { console.info('Device attached:', info.mechInfo); // Process the device connection logic. } else if (info.state === mechanicManager.AttachState.DETACHED) { console.info('Device detached:', info.mechInfo); // Process the device disconnection logic. } }; // Register a listener for attachStateChange events. mechanicManager.on('attachStateChange', attachStateChangeCallback); -
Process device connection and disconnection events.
const savedMechanicIds: number[] = []; const attachStateChangeCallback = (info: mechanicManager.AttachStateChangeInfo) => { if (info.state === mechanicManager.AttachState.ATTACHED) { console.info('Device attached:', info.mechInfo); savedMechanicIds.push(info.mechInfo.mechId); // To do sth. } else if (info.state === mechanicManager.AttachState.DETACHED) { console.info('Device detached:', info.mechInfo); savedMechanicIds.filter(id => id !== info.mechInfo.mechId); // To do sth. } }; // Register a listener for attachStateChange events. mechanicManager.on('attachStateChange', attachStateChangeCallback); -
Cancel listening for device connection state changes.
const savedMechanicIds: number[] = []; const attachStateChangeCallback = (info: mechanicManager.AttachStateChangeInfo) => { if (info.state === mechanicManager.AttachState.ATTACHED) { console.info('Device attached:', info.mechInfo); savedMechanicIds.push(info.mechInfo.mechId); // To do sth. } else if (info.state === mechanicManager.AttachState.DETACHED) { console.info('Device detached:', info.mechInfo); savedMechanicIds.filter(id => id !== info.mechInfo.mechId); // To do sth. } }; // Cancel listening for device connection state changes. mechanicManager.off('attachStateChange', attachStateChangeCallback);
Controlling Device Rotation
Precise rotation control, such as angle adjustment and motion trajectory control, helps you to implement flexible operation functions for mechanic devices.
-
Query the current status and restrictions of a device.
try { const savedMechanicIds: number[] = []; // Initialize device functions, such as obtaining the device status. const devices = mechanicManager.getAttachedMechDevices(); console.info('Connected devices:', devices); devices.forEach(device => { console.info(`Device ID: ${device.mechId}`); console.info(`Device Name: ${device.mechName}`); console.info(`Device Type: ${device.mechDeviceType}`); savedMechanicIds.push(device.mechId); }); // Register the listener for device connection state changes. const attachStateChangeCallback = (info: mechanicManager.AttachStateChangeInfo) => { if (info.state === mechanicManager.AttachState.ATTACHED) { console.info('Device attached:', info.mechInfo); } else if (info.state === mechanicManager.AttachState.DETACHED) { console.info('Device detached:', info.mechInfo); } }; mechanicManager.on('attachStateChange', attachStateChangeCallback); // Obtain the current angle of the device. const currentAngles = mechanicManager.getCurrentAngles(savedMechanicIds[0]); console.info('current angle:', currentAngles); // Obtain the rotation limit of the device. const rotationLimits = mechanicManager.getRotationLimits(savedMechanicIds[0]); console.info('Rotation limit:', rotationLimits); // Obtain the maximum rotation speed of the device. const maxSpeed = mechanicManager.getMaxRotationSpeed(savedMechanicIds[0]); console.info('Maximum rotation speed:', maxSpeed); // Obtain the maximum duration for continuous rotation of the device. const maxTime = mechanicManager.getMaxRotationTime(savedMechanicIds[0]); console.info('Maximum spin time:', maxTime); } catch (err) { console.error('Failed to query device status:', err); } -
Rotate the device by a relative angle.
const savedMechanicIds: number[] = []; // Initialize device functions, such as obtaining the device status. const devices = mechanicManager.getAttachedMechDevices(); console.info('Connected devices:', devices); devices.forEach(device => { savedMechanicIds.push(device.mechId); }); // Disable the camera tracking function before rotating the device. mechanicManager.setCameraTrackingEnabled(false); try { const mechId = savedMechanicIds[0]; // Device ID. // Obtain the current angle of the device. const currentAngles = mechanicManager.getCurrentAngles(mechId); if (!currentAngles||currentAngles.yaw === undefined||currentAngles.pitch === undefined|| currentAngles.roll === undefined) { console.error('Failed to retrieve current angles or angles are undefined.'); return; } // Obtain the rotation limit of the device. const rotationLimits = mechanicManager.getRotationLimits(mechId); if (!rotationLimits||rotationLimits.negativeYawMax === undefined|| rotationLimits.positiveYawMax === undefined|| rotationLimits.negativePitchMax === undefined||rotationLimits.positivePitchMax === undefined|| rotationLimits.negativeRollMax === undefined||rotationLimits.positiveRollMax === undefined) { console.error('Failed to retrieve rotation limits or limits are undefined.'); return; } console.info('Rotation limits:', rotationLimits); // Define the target angle. const angles: mechanicManager.RotationAngles = { yaw: Math.PI / 4, // Yaw angle: 45 degrees pitch: Math.PI / 6, // Pitch angle: 30 degrees roll: 0 // Roll angle: 0 degrees }; // Check whether the target angle exceeds the limit. if (currentAngles.yaw + (angles.yaw ?? 0) > rotationLimits.negativeYawMax|| currentAngles.yaw + (angles.yaw ?? 0) < rotationLimits.positiveYawMax|| currentAngles.pitch + (angles.pitch ?? 0) > rotationLimits.negativePitchMax|| currentAngles.pitch + (angles.pitch ?? 0) < rotationLimits.positivePitchMax|| currentAngles.roll + (angles.roll ?? 0) > rotationLimits.negativeRollMax|| currentAngles.roll + (angles.roll ?? 0) < rotationLimits.positiveRollMax ) { console.error('Target angles exceed rotation limits.'); return; } const duration = 2000; // Rotation duration: 2 seconds // Perform rotation. mechanicManager.rotate(mechId, angles, duration) .then((result) => { console.info(`Rotation Result: ${result}`); }); } catch (err) { console.error('Failed to rotate relative angle:', err); } -
Perform rotation at the specified speed until the task is complete.
try { const savedMechanicIds: number[] = []; // Initialize device functions, such as obtaining the device status. const devices = mechanicManager.getAttachedMechDevices(); console.info('Connected devices:', devices); devices.forEach(device => { savedMechanicIds.push(device.mechId); }); const mechId = savedMechanicIds[0]; // Assume that the first device is used. // Obtain the maximum rotation duration. const maxTime = mechanicManager.getMaxRotationTime(mechId); console.info('Maximum spin time:', maxTime); // Obtain the maximum rotation speed. const maxSpeed = mechanicManager.getMaxRotationSpeed(mechId); if (!maxSpeed||maxSpeed.yawSpeed === undefined||maxSpeed.pitchSpeed === undefined|| maxSpeed.rollSpeed === undefined) { console.error('Failed to retrieve maximum rotation speed or speed values are undefined.'); return; } console.info('Maximum rotation speed:', maxSpeed); // Define the rotation speed and duration. const speed: mechanicManager.RotationSpeed = { yawSpeed: maxSpeed.yawSpeed / 2, // Yaw speed: half of the maximum speed pitchSpeed: maxSpeed.pitchSpeed / 2, // Pitch speed: half of the maximum speed rollSpeed: maxSpeed.rollSpeed / 2 // Roll speed: half of the maximum speed }; const duration = Math.min(maxTime, 5000); // Duration: 5 seconds at most // Perform rotation. mechanicManager.rotateBySpeed(mechId, speed, duration) .then((result) => { console.info(`Rotation Result: ${result}`); }); } catch (err) { console.error('Failed to rotate by speed:', err); } -
Register a listener for rotation axis state changes.
const rotationAxesCallback = (info: mechanicManager.RotationAxesStateChangeInfo) => { console.info('Rotation Axes state change:', info); const mechId = info.mechId; const status = info.status; console.info(`Device ${mechId} status update:`); console.info(`- Yaw axes enabled: ${status.yawEnabled}`); console.info(`- Pitch axes enabled: ${status.pitchEnabled}`); console.info(`- Roll axes enabled: ${status.rollEnabled}`); if (status.yawLimited !== undefined) { console.info(`- Yaw axis restriction state: ${status.yawLimited}`); } }; // Register a listener for rotationAxesStatusChange events. mechanicManager.on('rotationAxesStatusChange', rotationAxesCallback); -
Stop the device movement.
try { const savedMechanicIds: number[] = []; // Initialize device functions, such as obtaining the device status. const devices = mechanicManager.getAttachedMechDevices(); console.info('Connected devices:', devices); devices.forEach(device => { savedMechanicIds.push(device.mechId); }); const mechId = savedMechanicIds[0]; mechanicManager.stopMoving(mechId); console.info('The device has ceased moving.'); } catch (err) { console.error('Failed to stop device movement:', err); }
Debugging and Verification
To ensure proper functioning of Mechanic Manager, perform the following steps for debugging and verification:
Connection Setup
- Ensure that the mechanic device is paired with and connected to the development device via Bluetooth.
- Place the development device on the mechanic device.
Test Procedure
- Querying the device list: Call
getAttachedMechDevicesto query the list of connected mechanic devices and check whether all mechanic devices are correctly identified. - Controlling device rotation: Call
setCameraTrackingEnabledto disable the camera tracking function and callgetCameraTrackingEnabledto verify the status. Then, callrotateorrotateBySpeedto control the rotation of the mechanic device.
Test Result Description
- If a list containing all mechanic device is returned after
getAttachedMechDevicesis called, the device identification is normal. - If the device starts to rotate as expected after
rotateorrotateBySpeedis called, the device rotation is normal.
你可能感兴趣的鸿蒙文章
openharmony 鸿蒙 camera-tracking-guide