Profile Position Mode (Large-Angle Control)
Mode Principle
The Profile Position Mode has built-in trajectory planning. After inputting a target position, the actuator will plan a smooth trajectory on its own and rotate along that trajectory until it reaches the target position. Before reaching the previous target position, the actuator will ignore other control messages it receives. This mode is suitable for large-angle control but does not support high-frequency control commands.
Parameter Configuration
- Parameters affecting the trajectory: acceleration and deceleration values in velocity mode, and PID parameters for the current loop, velocity loop, and position loop. These values can be changed in real time, even with high-frequency command messages. For modifying PID parameters, please refer to the PID parameter setting section.
- Parameters affecting actuator execution results: current limit, speed limit, and target position. These values can only be changed after the actuator has reached the previous target position.
- For messages used to set the above parameters, please refer to the CAN2.0B communication protocol.
Example Code
Python:
from motor_control import *
# port_name: Windows: "COM*" Linux: "/dev/ttyUSB*"
# id: Executor ID
# Baudrate: The baud rate can only be 921600
port_name = "COM6"
id = [0x00]
Baudrate = 921600
motor = MotorControl(port_name, id, Baudrate)
# Feedback_cycle1(ms): Feedback period of the first status packet,
# Including voltage, pwm, current, speed
# Feedback_cycle2(ms):Feedback period of the second status packet,
# Including the position of the motor and the position of the actuator
# Feedback_cycle3(ms):Feedback period of the third status packet,
# Including MOS tube, motor temperature, chip temperature and warning information,
# error information, operation mode
# cur: current(mA)
Feedback_cycle1 = 10
Feedback_cycle2 = 10
Feedback_cycle3 = 10
# PROFILE_POSITION_MODE
# limit_cur(mA): limit current
# limit_vel(rpm): the limit velocity of motor
# pos(count): target position, With a 16-bit encoder, the actuator counts 65536 per revolution.
limit_cur = [10000]
limit_vel = [1000]
pos = [20000]
reset(motor)
time.sleep(0.6)
mode_selection(motor, PROFILE_POSITION_MODE, Feedback_cycle1, Feedback_cycle2, Feedback_cycle3)
time.sleep(1)
# velocity_acc_dec_set(motor, {2000}, {2000})
# current_pid_set(motor, {0.006}, {0.001})
# velocity_pid_set(motor, {50}, {1.2})
# position_pid_set(motor, {0.008}, {0})
write_profile_position(motor, limit_cur, limit_vel, pos)
time.sleep(5)
position = get_pos(motor)[0][-1] # return the content of the second status packet
write_profile_position(motor, limit_cur, limit_vel, {0})
time.sleep(5)
c++:
#include <motor_control.h>
#include <multi_motor_control.h>
#include <iostream>
#include <thread>
#include <chrono>
#ifdef _WIN32
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")
#endif
#define delay(s) std::this_thread::sleep_for(std::chrono::milliseconds((int32_t)(s*1000)))
int main()
{
#ifdef _WIN32
timeBeginPeriod(1);
#endif
#define status_packet1 0xb1
#define status_packet2 0xb2
#define status_packet3 0xb3
// port_name: Windows: "COM*" Linux: "/dev/ttyUSB*"
// id: Executor ID
// Baudrate: The baud rate can only be 921600
string port_name = "COM6";
uint32_t Baudrate = 921600;
uint8_t id = 0x00;
MotorControl motor(port_name, Baudrate, id);
// Feedback_cycle1(ms): Feedback period of the first status packet,
// Including voltage, pwm, current, speed
// Feedback_cycle2(ms):Feedback period of the second status packet,
// Including the position of the motor and the position of the actuator
// Feedback_cycle3(ms):Feedback period of the third status packet,
// Including MOS tube, motor, chip temperature and warning information,
// error information, current operation mode
// cur: current(mA)
uint8_t Feedback_cycle1 = 10;
uint8_t Feedback_cycle2 = 10;
uint8_t Feedback_cycle3 = 10;
// PROFILE_POSITION_MODE
// cur(mA): limit current
// vel(rpm): the limit velocity of motor
// pos(count): target position, With a 16-bit encoder, the actuator counts 65536 per revolution.
cur = 10000;
vel = 1000;
int32_t pos = 20000;
motor.reset();
delay(0.6);
motor.mode_selection(Mode::PROFILE_POSITION_MODE, Feedback_cycle1, Feedback_cycle2, Feedback_cycle3);
delay(0.6);
// motor.write_velocity_acc_dec(2000, 2000); // Params: acceleration, deceleration
// motor.write_current_pid(0.006, 0.001); // Params: KP, KI
// motor.write_velocity_pid(50, 1.2); // Params: KP, KI
// motor.write_position_pid(0.008, 0); // Params: KP, KD
motor.write_profile_position(cur, vel, 0);
delay(2);
motor.write_profile_position(cur, vel, pos);
cout << endl << "profile position mode" << endl;
printf("target_position: %d\n", pos);
delay(5);
MotorStatus status = motor.get_motor_status({status_packet1,status_packet2,status_packet3});
printf("position: %d\n", status.actuator_position_value);
motor.write_profile_position(cur, vel, 0);
delay(3);
#ifdef _WIN32
timeEndPeriod(1);
#endif
}