package org.myrobotlab.service;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.myrobotlab.control.ServoOrchestratorGUI_middlemiddle_panel;
import org.myrobotlab.framework.Service;
import org.myrobotlab.framework.ServiceType;
import org.myrobotlab.logging.Level;
import org.myrobotlab.logging.LoggerFactory;
import org.myrobotlab.logging.Logging;
import org.myrobotlab.logging.LoggingFactory;
import org.myrobotlab.service.interfaces.ServiceInterface;
import org.slf4j.Logger;
/**
*
* @author LunDev (github), Ma. Vo. (MyRobotlab)
*/
public class ServoOrchestrator extends Service {
public class ClockThread implements Runnable {
public Thread thread = null;
ClockThread() {
thread = new Thread(this, getName() + "_ticking_thread");
thread.start();
}
@Override
public void run() {
try {
while (isClockRunning == true) {
play_play_3_1();
Thread.sleep(interval);
}
} catch (InterruptedException e) {
Logging.logError(e);
isClockRunning = false;
}
}
}
public class SettingsItemHolder {
public String name;
public int min;
public int max;
public int startvalue;
public int arduinopos;
public int pinpos;
public boolean attached;
}
private static final long serialVersionUID = 1L;
public final static Logger log = LoggerFactory.getLogger(ServoOrchestrator.class);
transient org.myrobotlab.control.ServoOrchestratorGUI sogui_ref;
int sizex = 5;
int sizey = 5;
SettingsItemHolder[] settingsitemholder;
Servo[] servos;
public boolean isClockRunning;
public int interval = 1;
public transient ClockThread myClock = null;
int middleright_shownitem;
boolean click_play = true;
int pos1;
int pos2;
int pos3;
public static void main(String[] args) throws InterruptedException {
LoggingFactory.init(Level.INFO);
try {
Runtime.start("gui", "GUIService");
Runtime.start("servoorchestrator", "ServoOrchestrator");
} catch (Exception e) {
Logging.logError(e);
}
}
public ServoOrchestrator(String n) {
super(n);
// intializing variables
settingsitemholder = new SettingsItemHolder[sizey];
for (int i = 0; i < settingsitemholder.length; i++) {
SettingsItemHolder sih = new SettingsItemHolder();
sih.name = "Channel " + (i + 1);
sih.min = 0;
sih.max = 180;
sih.startvalue = (sih.min + sih.max) / 2;
sih.arduinopos = 0;
sih.pinpos = 0;
sih.attached = false;
settingsitemholder[i] = sih;
}
servos = new Servo[sizey];
pos1 = 1;
pos2 = 1;
pos3 = 000;
}
public void bottommiddlerightbottom_button_1() {
play_go_ba();
}
public void bottommiddlerightbottom_button_2() {
play_go_fa();
}
public void bottommiddlerightbottom_button_3() {
play_go_b1();
}
public void bottommiddlerightbottom_button_4() {
play_go_f1();
}
public void bottommiddlerightbottom_button_5() {
// TODO - add functionality
}
public void bottommiddlerightbottom_button_6() {
play_go_stop();
}
public void bottommiddlerightbottom_button_7() {
play_go_start();
}
public void bottommiddlerightbottom_button_8() {
// TODO - add functionality
}
public void bottommiddlerighttop_update_button() {
pos1 = Integer.parseInt(sogui_ref.bottommiddlerighttop_textfield_1.getText());
pos2 = Integer.parseInt(sogui_ref.bottommiddlerighttop_textfield_2.getText());
pos3 = Integer.parseInt(sogui_ref.bottommiddlerighttop_textfield_3.getText());
play_updatetime(true, true, true);
play_updatepanels(pos1);
}
public void bottomright_click_checkbox() {
click_play = sogui_ref.bottomright_click_checkbox.isSelected();
}
public void externalcall_loadsettings(int pos) {
middleright_shownitem = pos;
sogui_ref.middleright_name_textfield.setText(settingsitemholder[pos].name);
sogui_ref.middleright_min_textfield.setText(settingsitemholder[pos].min + "");
sogui_ref.middleright_max_textfield.setText(settingsitemholder[pos].max + "");
sogui_ref.middleright_startvalue_textfield.setText(settingsitemholder[pos].startvalue + "");
sogui_ref.middleright_arduino_list.setSelectedIndex(settingsitemholder[middleright_shownitem].arduinopos);
sogui_ref.middleright_pin_list.setSelectedIndex(settingsitemholder[middleright_shownitem].pinpos);
if (!settingsitemholder[middleright_shownitem].attached) {
sogui_ref.middleright_attach_button.setText("Attach");
} else {
sogui_ref.middleright_attach_button.setText("Detach");
}
}
public void externalcall_servopanelchangeinfo(int x, int y) {
sogui_ref.middlemiddle_ref.panels[x][y].servo_min.setText(settingsitemholder[y].min + "");
sogui_ref.middlemiddle_ref.panels[x][y].servo_max.setText(settingsitemholder[y].max + "");
}
public void externalcall_servopanelsettostartpos(int x, int y, boolean withgoal) {
sogui_ref.middlemiddle_ref.panels[x][y].servo_start.setText(settingsitemholder[y].startvalue + "");
if (withgoal) {
sogui_ref.middlemiddle_ref.panels[x][y].servo_goal.setText(settingsitemholder[y].startvalue + "");
}
}
public void middleleft_channeladd_button() {
sizey++;
sogui_ref.sizey = sizey;
sogui_ref.middlemiddle_ref.externallcall_refreshsize();
refreshsize();
}
public void middleleft_channelremove_button() {
sizey--;
sogui_ref.sizey = sizey;
sogui_ref.middlemiddle_ref.externallcall_refreshsize();
refreshsize();
}
public void middleleft_timeunitadd_button() {
sizex++;
sogui_ref.sizex = sizex;
sogui_ref.middlemiddle_ref.externallcall_refreshsize();
}
public void middleleft_timeunitremove_button() {
sizex--;
sogui_ref.sizex = sizex;
sogui_ref.middlemiddle_ref.externallcall_refreshsize();
}
public void middleright_arduino_list() {
String selvalue = (String) sogui_ref.middleright_arduino_list.getSelectedValue();
if (selvalue == null) {
} else if (selvalue.equals(" ")) {
// 1.
} else if (selvalue.equals("refresh")) {
// 2.
set_middleright_arduino_list_items();
} else {
// 3.+
}
}
public void middleright_attach_button() throws Exception {
if (!settingsitemholder[middleright_shownitem].attached) {
settingsitemholder[middleright_shownitem].arduinopos = sogui_ref.middleright_arduino_list.getSelectedIndex();
settingsitemholder[middleright_shownitem].pinpos = sogui_ref.middleright_pin_list.getSelectedIndex();
String arduinoName = (String) sogui_ref.middleright_arduino_list.getSelectedValue();
Arduino arduino = (Arduino)Runtime.getService(arduinoName);
int pin = Integer.parseInt((String) sogui_ref.middleright_pin_list.getSelectedValue());
int min = settingsitemholder[middleright_shownitem].min;
int max = settingsitemholder[middleright_shownitem].max;
servos[middleright_shownitem] = (Servo) Runtime.start("so." + middleright_shownitem, "Servo");
servos[middleright_shownitem].setMinMax(min, max);
arduino.servoAttach(servos[middleright_shownitem], pin);
servos[middleright_shownitem].attach();
sogui_ref.middleright_attach_button.setText("Detach");
settingsitemholder[middleright_shownitem].attached = true;
} else {
servos[middleright_shownitem].detach();
servos[middleright_shownitem] = null;
sogui_ref.middleright_attach_button.setText("Attach");
settingsitemholder[middleright_shownitem].attached = false;
}
}
public void middleright_update_button() {
settingsitemholder[middleright_shownitem].name = sogui_ref.middleright_name_textfield.getText();
settingsitemholder[middleright_shownitem].min = Integer.parseInt(sogui_ref.middleright_min_textfield.getText());
settingsitemholder[middleright_shownitem].max = Integer.parseInt(sogui_ref.middleright_max_textfield.getText());
settingsitemholder[middleright_shownitem].startvalue = Integer.parseInt(sogui_ref.middleright_startvalue_textfield.getText());
sogui_ref.middlemiddle_ref.prep[middleright_shownitem].channel_name.setText(settingsitemholder[middleright_shownitem].name);
if (settingsitemholder[middleright_shownitem].attached) {
int min = settingsitemholder[middleright_shownitem].min;
int max = settingsitemholder[middleright_shownitem].max;
servos[middleright_shownitem].setMinMax(min, max);
}
for (int i = 0; i < sogui_ref.middlemiddle_ref.panels.length; i++) {
if (sogui_ref.middlemiddle_ref.panels[i][middleright_shownitem] != null) {
sogui_ref.middlemiddle_ref.panels[i][middleright_shownitem].servo_min.setText(settingsitemholder[middleright_shownitem].min + "");
sogui_ref.middlemiddle_ref.panels[i][middleright_shownitem].servo_max.setText(settingsitemholder[middleright_shownitem].max + "");
}
}
// TODO - change the "startvalue"
}
public void play_checktime() {
if (pos1 > sogui_ref.middlemiddle_ref.panels[0].length) {
pos1 = sogui_ref.middlemiddle_ref.panels[0].length;
} else if (pos1 < 1) {
pos1 = 1;
}
if (pos2 > 4) {
pos2 = 4;
} else if (pos2 < 1) {
pos2 = 1;
}
if (pos3 > 999) {
pos3 = 999;
} else if (pos3 < 0) {
pos3 = 0;
}
}
public void play_go_b1() {
pos1--;
play_updatetime(true, false, false);
play_updatepanels(pos1);
}
public void play_go_ba() {
pos1 = 1;
pos2 = 1;
pos3 = 0;
play_updatetime(true, true, true);
play_updatepanels(pos1);
}
public void play_go_f1() {
pos1++;
play_updatetime(true, false, false);
play_updatepanels(pos1);
}
public void play_go_fa() {
pos1 = sogui_ref.middlemiddle_ref.panels[0].length;
pos2 = 4;
pos3 = 999;
play_updatetime(true, true, true);
play_updatepanels(pos1);
}
public void play_go_start() {
sogui_ref.bottommiddlerightbottom_button_6.setEnabled(true);
sogui_ref.bottommiddlerightbottom_button_7.setEnabled(false);
startClock();
}
public void play_go_stop() {
sogui_ref.bottommiddlerightbottom_button_6.setEnabled(false);
sogui_ref.bottommiddlerightbottom_button_7.setEnabled(true);
stopClock();
}
public void play_play_1_1() {
pos1++;
if (pos1 > sizex) {
play_go_stop();
pos2 = 4;
pos3 = 999;
}
play_updatetime(true, false, false);
play_playreally(pos1);
}
public void play_play_2_1() {
pos2++;
if (pos2 > 4) {
pos2 -= 4;
play_play_1_1();
}
play_updatetime(false, true, false);
}
public void play_play_3_1() {
// first block
if (pos1 == 1 && pos2 == 1 && pos3 == 0) {
play_playreally(pos1);
}
pos3++;
if (pos3 > 999) {
pos3 -= 999;
play_play_2_1();
}
play_updatetime(false, false, true);
}
public void play_playblock(int channel, ServoOrchestratorGUI_middlemiddle_panel block) {
switch (block.type) {
case "timesection":
break;
case "channel":
break;
case "servo":
if (servos[channel] != null) {
int movetopos = Integer.parseInt(block.servo_goal.getText());
servos[channel].moveTo(movetopos);
}
break;
}
}
public void play_playclick() {
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(getClass().getResourceAsStream("/resource/ServoOrchestrator/click.wav"));
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
} catch (Exception e) {
Logging.logError(e);
}
}
public void play_playreally(int pos) {
play_updatepanels(pos);
if (click_play) {
play_playclick();
}
if (pos <= sizex) {
play_searchblocks(pos);
}
}
public void play_searchblocks(int pos) {
for (int i = 0; i < sizey; i++) {
ServoOrchestratorGUI_middlemiddle_panel panels11 = sogui_ref.middlemiddle_ref.panels[pos - 1][i];
if (panels11 != null) {
play_playblock(i, panels11);
}
}
}
public void play_updatepanels(int pos) {
for (int i = 0; i < sogui_ref.middlemiddle_ref.panels[0].length; i++) {
sogui_ref.middlemiddle_ref.prep[sogui_ref.middlemiddle_ref.panels[0].length + i].setBackground(Color.green);
}
sogui_ref.middlemiddle_ref.prep[sogui_ref.middlemiddle_ref.panels[0].length + pos - 1].setBackground(Color.red);
sogui_ref.middlemiddle_ref.relayout();
}
public void play_updatetime(boolean t1, boolean t2, boolean t3) {
play_checktime();
if (t1) {
sogui_ref.bottommiddlerighttop_textfield_1.setText(pos1 + "");
}
if (t2) {
sogui_ref.bottommiddlerighttop_textfield_2.setText(pos2 + "");
}
if (t3) {
sogui_ref.bottommiddlerighttop_textfield_3.setText(pos3 + "");
}
}
public void refreshsize() {
SettingsItemHolder[] settingsitemholderold = new SettingsItemHolder[sizey];
settingsitemholderold = settingsitemholder.clone();
Servo[] servosold = new Servo[sizey];
settingsitemholder = new SettingsItemHolder[sizey];
for (int i = 0; i < settingsitemholder.length; i++) {
if (i >= settingsitemholderold.length) {
SettingsItemHolder sih = new SettingsItemHolder();
sih.name = "Channel " + (i + 1);
sih.min = 0;
sih.max = 180;
sih.startvalue = (sih.min + sih.max) / 2;
sih.arduinopos = 0;
sih.pinpos = 0;
sih.attached = false;
settingsitemholder[i] = sih;
continue;
}
settingsitemholder[i] = settingsitemholderold[i];
}
servos = new Servo[sizey];
for (int i = 0; i < servos.length; i++) {
if (i >= servosold.length) {
continue;
}
servos[i] = servosold[i];
}
}
public void set_middleright_arduino_list_items() {
List<ServiceInterface> services = Runtime.getServices();
ArrayList<String> arduinolist = new ArrayList<String>();
for (ServiceInterface service : services) {
String type = service.getType();
String typ = type.substring(23);
if (typ.equals("Arduino")) {
String name = service.getName();
arduinolist.add(name);
}
}
String[] arduinoarray = new String[arduinolist.size() + 2];
arduinoarray[0] = " ";
arduinoarray[1] = "refresh";
for (int i = 0; i < arduinolist.size(); i++) {
arduinoarray[i + 2] = arduinolist.get(i);
}
sogui_ref.middleright_arduino_list.setListData(arduinoarray);
}
public void setmiddlemiddlesize() {
sogui_ref.sizex = sizex;
sogui_ref.sizey = sizey;
}
public void setsoguireference(org.myrobotlab.control.ServoOrchestratorGUI so_ref) {
sogui_ref = so_ref;
}
public void startClock() {
if (myClock == null) {
isClockRunning = true;
myClock = new ClockThread();
}
}
public void stopClock() {
if (myClock != null) {
isClockRunning = false;
myClock.thread.interrupt();
myClock.thread = null;
myClock = null;
}
isClockRunning = false;
}
public void top_addservo_button() {
sogui_ref.middlemiddle_ref.externalcall_addPanel();
}
public void top_load_button() {
try {
BufferedReader br = new BufferedReader(new FileReader("scratchconfig.txt"));
int counter = 0;
int type = 0;
String line;
while ((line = br.readLine()) != null) {
if (line.equals("#size")) {
counter = 0;
type = 1;
} else if (line.equals("#sih")) {
counter = 0;
type = 2;
} else if (line.equals("#prep")) {
counter = 0;
type = 3;
} else if (line.equals("#panels")) {
counter = 0;
type = 4;
} else if (type == 1) {
int size = Integer.parseInt(line);
if (counter == 0) {
sizex = size;
sogui_ref.sizex = sizex;
sogui_ref.middlemiddle_ref.externallcall_refreshsize();
} else if (counter == 1) {
sizey = size;
sogui_ref.sizey = sizey;
sogui_ref.middlemiddle_ref.externallcall_refreshsize();
refreshsize();
} else {
sogui_ref.middlemiddle_ref.panel_counter = size;
}
counter++;
} else if (type == 2) {
String[] linesplit = line.split("~");
settingsitemholder[counter].name = linesplit[0];
settingsitemholder[counter].min = Integer.parseInt(linesplit[1]);
settingsitemholder[counter].max = Integer.parseInt(linesplit[2]);
settingsitemholder[counter].startvalue = Integer.parseInt(linesplit[3]);
settingsitemholder[counter].arduinopos = Integer.parseInt(linesplit[4]);
settingsitemholder[counter].pinpos = Integer.parseInt(linesplit[5]);
settingsitemholder[counter].attached = Boolean.parseBoolean(linesplit[6]);
counter++;
} else if (type == 3) {
String[] linesplit = line.split("~");
sogui_ref.middlemiddle_ref.prep[counter] = new ServoOrchestratorGUI_middlemiddle_panel(linesplit);
if (linesplit[0].equals("channel")) {
final int counterf = counter;
sogui_ref.middlemiddle_ref.prep[counter].channel_settings.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
externalcall_loadsettings(counterf);
}
});
} else if (linesplit[0].equals("timesection")) {
sogui_ref.middlemiddle_ref.prep[counter].timesection_headline.setText("TIMEUNIT " + (counter - sizey + 1));
}
sogui_ref.middlemiddle_ref.relayout();
counter++;
} else if (type == 4) {
if (line.equals("null")) {
sogui_ref.middlemiddle_ref.panels[counter / sizey][counter % sizey] = null;
} else if (sogui_ref.middlemiddle_ref.panels[counter / sizey][counter % sizey] == null) {
String[] linesplit = line.split("~");
sogui_ref.middlemiddle_ref.panels[counter / sizey][counter % sizey] = new ServoOrchestratorGUI_middlemiddle_panel(linesplit);
final int counterf = counter;
sogui_ref.middlemiddle_ref.panels[counter / sizey][counter % sizey].servo_goal.getDocument().addDocumentListener(new DocumentListener() {
public void adjust() {
int i1 = counterf / sizey;
int i2 = counterf % sizey;
int searchpos = i1 + 1;
while (searchpos < sogui_ref.middlemiddle_ref.panels.length) {
if (sogui_ref.middlemiddle_ref.panels[searchpos][i2] == null) {
searchpos++;
} else {
sogui_ref.middlemiddle_ref.panels[searchpos][i2].servo_start
.setText(sogui_ref.middlemiddle_ref.panels[counterf / sizey][counterf % sizey].servo_goal.getText() + "");
break;
}
}
}
@Override
public void changedUpdate(DocumentEvent e) {
adjust();
}
@Override
public void insertUpdate(DocumentEvent e) {
adjust();
}
@Override
public void removeUpdate(DocumentEvent e) {
adjust();
}
});
}
sogui_ref.middlemiddle_ref.relayout();
counter++;
}
}
br.close();
} catch (IOException e) {
Logging.logError(e);
}
}
public void top_save_button() {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("scratchconfig.txt"));
bw.write("#size");
bw.newLine();
bw.write(sizex + "");
bw.newLine();
bw.write(sizey + "");
bw.newLine();
bw.write(sogui_ref.middlemiddle_ref.panel_counter + "");
bw.newLine();
bw.write("#sih");
bw.newLine();
for (SettingsItemHolder sih : settingsitemholder) {
bw.write(sih.name + "~" + sih.min + "~" + sih.max + "~" + sih.startvalue + "~" + sih.arduinopos + "~" + sih.pinpos + "~" + sih.attached);
bw.newLine();
}
bw.write("#prep");
bw.newLine();
for (ServoOrchestratorGUI_middlemiddle_panel p : sogui_ref.middlemiddle_ref.prep) {
bw.write(p.type + "~" + p.id + "~" + p.channel_name.getText() + "~" + p.servo_start.getText() + "~" + p.servo_channelid.getText() + "~" + p.servo_goal.getText() + "~"
+ p.servo_min.getText() + "~" + p.servo_max.getText());
bw.newLine();
}
bw.write("#panels");
bw.newLine();
for (ServoOrchestratorGUI_middlemiddle_panel[] p1 : sogui_ref.middlemiddle_ref.panels) {
for (ServoOrchestratorGUI_middlemiddle_panel p : p1) {
if (p != null) {
bw.write(p.type + "~" + p.id + "~" + p.channel_name.getText() + "~" + p.servo_start.getText() + "~" + p.servo_channelid.getText() + "~" + p.servo_goal.getText() + "~"
+ p.servo_min.getText() + "~" + p.servo_max.getText());
} else {
bw.write("null");
}
bw.newLine();
}
}
bw.close();
} catch (IOException e) {
Logging.logError(e);
}
}
/**
* This static method returns all the details of the class without it having
* to be constructed. It has description, categories, dependencies, and peer
* definitions.
*
* @return ServiceType - returns all the data
*
*/
static public ServiceType getMetaData() {
ServiceType meta = new ServiceType(ServoOrchestrator.class.getCanonicalName());
meta.addDescription("organize your Servo-movements");
meta.addCategory("motor", "control", "display");
return meta;
}
}