Linear Stage in JavaΒΆ
This example demonstrates the initialization of a linear stage and then randomly generated moves between the limit switches.
public class MyPimotionTest
{
public static Stage s;
public static void main(String[] args)
{
s = new Stage("192.168.1.200");
while (true) {
s.move_to_random(true);
}
}
}
import com.vena.Pilib;
import com.vena.Pilib.MtrSegment;
import com.vena.Pilib.TrapezoidalEntry;
import com.vena.Pilib.VelocityEntry;
import com.vena.Pilib.Trigger;
import com.vena.Pilib.ServoMode;
import java.util.Random;
public class Stage extends Pilib {
public class MtrConf {
public int elec_cycle_div = 50000;
public double kp = 1250.0;
public double ki = 10.0;
public double kd = 340.0;
public int ilim = 1000;
public int max_pid_output = 30000;
public int enc_counts_per_rot = 2048;
public int poles = 4;
public int phases = 3;
public int reset_current = 28000;
public int reset_wait_time_ms = 3000;
public int max_pos_error = 1500;
public int use_aux_enc_for_servo =0;
public int output_polarity = 0;
public int encoder_polarity = 0;
}
public Pilib p;
MtrConf conf;
long left;
long right;
TrapezoidalEntry[] entries;
MtrSegment[] segments;
int num_segments;
double last_vel;
Random rand;
public Stage(String address)
{
super(address,"password",0);
conf = new MtrConf();
rand = new Random();
entries = new TrapezoidalEntry[1];
entries[0] = new TrapezoidalEntry(0., 0, 5000., 8000., 8000.);
segments = new MtrSegment[3];
segments[0] = new MtrSegment();
segments[1] = new MtrSegment();
segments[2] = new MtrSegment();
// configure limit switches
gpio_set_direction(0xff, 0b11111110); // gpio 0 is output, all others input
gpio_set_pullup(0xff, 0b00000110); // pullup on gpio 1 & 2
gpio_set_value(0xff, 0x00); // set low
// get off limit switches to reset motor
if (gpio_get_value(0xff) != 0) {
mtr_set_pwr_enable(0);
print ("Move stage to the center...");
while (gpio_get_value(0xff) != 0) {
sleep(0.1);
}
sleep(2);
print("thanks!");
}
reset_motor();
last_vel = 0.0;
long start_pos = mtr_get_actual_pos();
find_endstop(-500, 0b00000010);
find_endstop(500, 0b00000000);
left = find_endstop(-50, 0b00000010);
move_to(start_pos, true);
find_endstop(500, 0b00000100);
find_endstop(-500, 0b00000000);
right = find_endstop(50, 0b00000100);
move_to(start_pos, true);
}
public void configure_motor()
{
mtr_set_mtr_type(0);
// set the pid and trajectory generator update rate
mtr_set_elec_cycle_div(conf.elec_cycle_div);
// set the pid gains (proportional, integral, derivitive)
mtr_set_kp(conf.kp);
mtr_set_ki(conf.ki);
mtr_set_kd(conf.kd);
mtr_set_ilim(conf.ilim);
// limit the output of the amplifiers
mtr_set_max_pid_output(conf.max_pid_output);
// set the number of encoder counts for one rotation of the motor
mtr_set_enc_counts_per_rot(conf.enc_counts_per_rot);
mtr_set_enc_polarity(conf.encoder_polarity);
// configure the number of poles the motor has
mtr_set_poles(conf.poles);
mtr_set_reset_current(conf.reset_current);
mtr_set_reset_wait_time_ms(conf.reset_wait_time_ms);
mtr_set_max_pos_error(conf.max_pos_error);
mtr_set_use_aux_enc_for_servo(conf.use_aux_enc_for_servo);
mtr_set_output_polarity(conf.output_polarity);
}
public void reset_motor()
{
configure_motor();
mtr_set_pwr_enable(1);
// configure the motor phase waveforms
mtr_write_phase_mem_default(conf.phases, conf.poles, conf.enc_counts_per_rot);
mtr_reset();
print ("Resetting...");
while (mtr_get_reset_state() != 0) {
sleep(0.1);
}
print("Finished resetting.");
}
public void stop()
{
long pos = mtr_get_actual_pos();
mtr_write_target_position(pos, 1);
}
public void start()
{
mtr_write_table(0, num_segments, segments);
mtr_start(0,Trigger.TRIG_SRC_NONE);
}
public void move_velocity(double velocity, double acceleration)
{
VelocityEntry profile[] = new VelocityEntry[1];
profile[0] = new VelocityEntry(0.0, velocity, acceleration);
num_segments = mtr_create_velocity_profile(last_vel, profile, ServoMode.SERVOMODE_POSITION, conf.elec_cycle_div, segments);
start();
last_vel = velocity;
}
public long find_endstop(int velocity, int gpio_val)
{
move_velocity(velocity, 1600);
while (mtr_get_motion_error() == 0)
{
long pos = mtr_get_actual_pos();
int val = gpio_get_value(0b00000110);
if (val == gpio_val)
{
stop();
mtr_set_motion_error(0);
return pos;
}
}
return 0;
}
public void move_to(long pos, boolean wait_for_complete)
{
long actual_pos = mtr_get_actual_pos();
if (actual_pos != pos) {
entries[0].position = pos;
num_segments = mtr_create_trapezoidal_profile(actual_pos, entries, conf.elec_cycle_div, segments);
start();
while (wait_for_complete && (mtr_get_profile_finished() == 0)) {
sleep(0.1);
}
}
}
public void move_to_random(boolean wait_for_complete)
{
long pos = randlong(left + 50, right - 50);
move_to(pos, wait_for_complete);
}
public long randlong(long min, long max)
{
return rand.nextInt((int)((max - min) + 1)) + min;
}
public void print(String data)
{
System.out.println(data);
}
public void sleep(double sec)
{
int ms = (int)(sec * 1000.0);
try {
Thread.sleep(ms);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
public void print_temp()
{
double temperature = pidev_get_temperature();
System.out.format("The temperature is %.2f C\n", temperature);
}
}