movemaster-robot
Version:
A module to control a Mitsubishi Movemaster EX RV-M1 robotic arm via USB
341 lines (249 loc) • 8.1 kB
Markdown
# Movemaster Robot Library
This project allows you to control a "vintage" Mitsubishi Movemaster EX Robot using Javascript via the serial RS232 port.

> This project relies heavily on the great work by Daniel Springwald – all documented [here](https://github.com/Springwald/Movemaster-RV-M1-Library).
## Installation
Install the library via npm:
```bash
npm install movemaster-robot
```
## Hardware Requirements
- Mitsubishi Movemaster EX RV-M1 robotic arm
- RS232 serial connection (USB-to-Serial adapter if needed)
- Computer with Node.js environment
## Quick Start
```javascript
import { Robot } from 'movemaster-robot';
const robot = new Robot();
async function main() {
// Connect to the robot via serial port
await robot.connect('/dev/ttyUSB0'); // Linux/Mac
// await robot.connect('COM3'); // Windows
// Initialize robot position
await robot.nest();
// Move to a specific position
await robot.moveTo({
x: 100,
y: 50,
z: 200,
p: 0,
r: 0
});
// Open gripper
await robot.setGripper(true);
// Close gripper
await robot.setGripper(false);
// Disconnect when done
robot.disconnect();
}
main().catch(console.error);
```
## API Reference
### Connection Management
#### `connect(comPortName: string): Promise<void>`
Connects to the robot via the specified serial port.
```javascript
await robot.connect('/dev/ttyUSB0'); // Linux/Mac
await robot.connect('COM3'); // Windows
```
#### `isConnected(): boolean`
Returns whether the robot is currently connected.
#### `disconnect(): void`
Closes the serial port connection.
#### `listPorts(): Promise<string[]>`
Lists all available serial ports on the system.
```javascript
const ports = await robot.listPorts();
console.log('Available ports:', ports);
```
### Movement Commands
#### `moveTo(position: Position, interpolatePoints?: number): Promise<void>`
Moves the robot to an absolute position.
```javascript
await robot.moveTo({
x: 100, // X coordinate in mm
y: 50, // Y coordinate in mm
z: 200, // Z coordinate in mm
p: 0, // Pitch angle in degrees
r: 0 // Roll angle in degrees
}, 10); // Optional: number of interpolation points for smooth movement
```
#### `moveToXYZ(x: number, y: number, z: number, interpolatePoints?: number): Promise<void>`
Moves to specific XYZ coordinates while maintaining current P and R values.
```javascript
await robot.moveToXYZ(150, 75, 180);
```
#### `moveDelta(x: number, y: number, z: number, interpolatePoints?: number): Promise<void>`
#### `moveDelta(x: number, y: number, z: number, p: number, r: number, interpolatePoints?: number): Promise<void>`
Moves the robot relative to its current position.
```javascript
// Move relative in XYZ only
await robot.moveDelta(10, 0, -5);
// Move relative in all axes
await robot.moveDelta(10, 0, -5, 15, 0);
```
#### `rotateAxis(x: number, y: number, z: number, p: number, r: number): Promise<void>`
Rotates axes relative to the current position.
#### `movePath(points: Position[]): Promise<void>`
Moves the robot through a series of positions.
```javascript
const path = [
{ x: 100, y: 50, z: 200, p: 0, r: 0 },
{ x: 150, y: 75, z: 180, p: 10, r: 5 },
{ x: 200, y: 100, z: 160, p: 0, r: 0 }
];
await robot.movePath(path);
```
#### `moveToHomePosition(): Promise<void>`
Moves all axes to zero position.
#### `nest(): Promise<void>`
Moves the robot to its mechanical origin position. Must be performed immediately after power on.
### Gripper Control
#### `setGripper(open: boolean): Promise<void>`
Opens or closes the gripper.
```javascript
await robot.setGripper(true); // Open gripper
await robot.setGripper(false); // Close gripper
```
#### `getGripperClosed(): boolean`
Returns whether the gripper is currently closed.
#### `setGripPressure(startingGripForce: number, retainedGrippingForce: number, startGrippingForceRetentionTime: number): Promise<void>`
Sets the gripper pressure parameters.
```javascript
await robot.setGripPressure(
10, // Starting grip force (0-15)
5, // Retained gripping force (0-15)
20 // Start gripping force retention time (0-99)
);
```
### Configuration
#### `setSpeed(speed: number): Promise<void>`
Sets the robot movement speed (0-9).
```javascript
await robot.setSpeed(5); // Medium speed
```
#### `setToolLength(length: number): Promise<void>`
Sets the tool length in mm.
```javascript
await robot.setToolLength(50); // 50mm tool
```
### Position and Status
#### `getActualPosition(forceUpdateByHardware?: boolean): Promise<Position>`
Gets the current robot position.
```javascript
const position = await robot.getActualPosition();
console.log('Current position:', position);
// { x: 100, y: 50, z: 200, p: 0, r: 0 }
```
#### `getPosition(): Position | null`
Returns the cached position without querying the hardware.
#### `getSpeed(): number`
Returns the current speed setting.
#### `getToolLength(): number`
Returns the current tool length setting.
### Error Handling
#### `checkRobotErrorCode(): Promise<{ok: true} | {ok: false, error: ROBOT_ERRORS}>`
Checks for robot errors.
```javascript
const result = await robot.checkRobotErrorCode();
if (!result.ok) {
console.error('Robot error:', result.error);
}
```
#### `withCheck<T>(result: Promise<T>): Promise<T>`
Executes a command and automatically checks for errors.
```javascript
await robot.withCheck(robot.moveTo({ x: 100, y: 50, z: 200, p: 0, r: 0 }));
```
### System Commands
#### `reset(): Promise<void>`
Resets the robot control box.
## Types
### Position
```typescript
type Position = {
x: number; // X coordinate in mm
y: number; // Y coordinate in mm
z: number; // Z coordinate in mm
p: number; // Pitch angle in degrees
r: number; // Roll angle in degrees
};
```
### Robot Errors
```typescript
enum ROBOT_ERRORS {
HARDWARE_ERROR = 1,
COMMAND_ERROR = 2,
UNKNOWN_ERROR = 99,
}
```
## Serial Port Configuration
The library uses the following default serial port settings:
- Baud Rate: 9600
- Data Bits: 7
- Stop Bits: 2
- Parity: Even
- RTS: true
- DTR: true
- Handshake: XOn/XOff
## Example: Complete Robot Operation
```javascript
import { Robot } from 'movemaster-robot';
async function robotDemo() {
const robot = new Robot();
try {
// Connect to robot
console.log('Connecting to robot...');
await robot.connect('/dev/ttyUSB0');
// Initialize robot
console.log('Initializing robot...');
await robot.nest();
await robot.setSpeed(5);
await robot.setToolLength(50);
// Get current position
const startPos = await robot.getActualPosition();
console.log('Start position:', startPos);
// Move to pickup position
console.log('Moving to pickup position...');
await robot.moveTo({ x: 150, y: 0, z: 100, p: 0, r: 0 });
// Open gripper and move down
await robot.setGripper(true);
await robot.moveDelta(0, 0, -50);
// Close gripper to pick up object
await robot.setGripper(false);
// Move up and to drop position
await robot.moveDelta(0, 0, 50);
await robot.moveTo({ x: -150, y: 0, z: 100, p: 0, r: 0 });
// Drop object
await robot.moveDelta(0, 0, -50);
await robot.setGripper(true);
await robot.moveDelta(0, 0, 50);
// Return to home
await robot.moveToHomePosition();
console.log('Demo completed successfully!');
} catch (error) {
console.error('Robot operation failed:', error);
} finally {
robot.disconnect();
}
}
robotDemo();
```
## Error Handling Best Practices
Always wrap robot operations in try-catch blocks and check for errors:
```javascript
try {
await robot.moveTo({ x: 100, y: 50, z: 200, p: 0, r: 0 });
const errorCheck = await robot.checkRobotErrorCode();
if (!errorCheck.ok) {
throw new Error(`Robot error: ${errorCheck.error}`);
}
} catch (error) {
console.error('Movement failed:', error);
// Handle error appropriately
}
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
MIT