BowlerKernel
TimeSequence.java
Go to the documentation of this file.
1 package com.neuronrobotics.bowlerstudio.sequence;
2 
3 import java.io.File;
4 import java.io.IOException;
5 import java.lang.reflect.Type;
6 import java.util.ArrayList;
7 import java.util.HashMap;
8 
9 import com.google.gson.Gson;
10 import com.google.gson.GsonBuilder;
11 import com.google.gson.reflect.TypeToken;
12 import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
13 import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
14 import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
15 import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
16 import com.neuronrobotics.sdk.common.DeviceManager;
17 import com.neuronrobotics.sdk.util.ThreadUtil;
18 
19 import javax.sound.sampled.AudioInputStream;
20 import javax.sound.sampled.AudioSystem;
21 import javax.sound.sampled.Clip;
22 import javax.sound.sampled.FloatControl;
23 import javax.sound.sampled.LineEvent;
24 import javax.sound.sampled.LineUnavailableException;
25 import javax.sound.sampled.UnsupportedAudioFileException;
26 
27 import org.eclipse.jgit.api.errors.GitAPIException;
28 import org.eclipse.jgit.api.errors.InvalidRemoteException;
29 import org.eclipse.jgit.api.errors.TransportException;
30 
31 public class TimeSequence {
32  // Create the type, this tells GSON what datatypes to instantiate when parsing
33  // and saving the json
34  private static Type TT_mapStringString = new TypeToken<HashMap<String, Object>>() {
35  }.getType();
36  private static Type TT_listString = new TypeToken<ArrayList<String>>() {
37  }.getType();
38  private static Type TT_SequenceEvent = new TypeToken<SequenceEvent>() {
39  }.getType();
40  private static Type TT_mapSequence = new TypeToken<HashMap<String, SequenceEvent>>() {
41  }.getType();
42  // chreat the gson object, this is the parsing factory
43  private Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
44  private HashMap<String, Object> database;
45  private HashMap<String, Object> initialize;
46  private String url;
47  private String file;
48  private String wavurl;
49  private String wavfile;
50  private long duration;
51  private ArrayList<String> devicesInSequence;
52 
53  public static HashMap<String, AbstractKinematicsNR> getDevices() {
54  HashMap<String, AbstractKinematicsNR> map = new HashMap<>();
55  for (String dev : DeviceManager.listConnectedDevice()) {
56  Object specificDevice = DeviceManager.getSpecificDevice(dev);
57  if (MobileBase.class.isInstance(specificDevice)) {
58  MobileBase specificDevice2 = (MobileBase) specificDevice;
59  loadMobileBase(map, specificDevice2, 0);
60  }
61  }
62  return map;
63  }
64 
65  private static void loadMobileBase(HashMap<String, AbstractKinematicsNR> map, MobileBase specificDevice2,
66  int depth) {
67  map.put("MobileBase:" + specificDevice2.getScriptingName() + " " + depth, specificDevice2);
68  for (DHParameterKinematics pg : specificDevice2.getAllParallelGroups()) {
69  map.put(specificDevice2.getScriptingName() + " " + "ParallelGroup:" + pg.getScriptingName() + " " + depth,
70  pg);
71  }
72  for (DHParameterKinematics kin : specificDevice2.getAllDHChains()) {
73  if (specificDevice2.getParallelGroup(kin) == null)
74  map.put(specificDevice2.getScriptingName() + " " + "Appendage:" + kin.getScriptingName() + " " + depth,
75  kin);
76  for (int i = 0; i < kin.getNumberOfLinks(); i++) {
77  MobileBase follower = kin.getSlaveMobileBase(i);
78  if (follower != null) {
79  loadMobileBase(map, follower, depth + 1);
80  }
81  }
82  }
83  }
84 
85  public void execute(String content) throws Exception {
86 
87  load(content);
88 
89  runSequence();
90  }
91 
92  public void runSequence() throws Exception {
93  System.out.println("Initialize Sequence");
95 
96  HashMap<String, AbstractKinematicsNR> devices = getDevices();
97  long start = System.currentTimeMillis();
98  ArrayList<Thread> threads = new ArrayList<Thread>();
99  if (getWavurl() != null && getWavfile() != null) {
100  addWavFileRun(threads);
101  }
102  long finalDur = getDuration();
103  for (String mine : devices.keySet()) {
104  for (String key : getDevicesInSequence())
105  if (mine.contentEquals(key)) {
106  System.out.println("Found Device " + key);
107  HashMap<String, SequenceEvent> devSeq = getSequence(key);
108  Thread t = new Thread(() -> {
109  for (int i = 0; i < finalDur && !Thread.interrupted(); i++) {
110  SequenceEvent event = devSeq.get("" + i);
111  if (event != null) {
112  System.out.println(key + " Execute @ " + i);
113  event.execute((DHParameterKinematics) devices.get(key));
114  }
115  try {
116  Thread.sleep(1);
117  } catch (InterruptedException e) {
118  return;
119  }
120  }
121  });
122  threads.add(t);
123  }
124  }
125  System.out.println("Running sequence");
126  for (Thread t : threads) {
127  t.start();
128  }
129  try {
130  for (Thread t : threads) {
131  t.join();
132  }
133  } catch (java.lang.InterruptedException ex) {
134  for (Thread t : threads) {
135  t.interrupt();
136  }
137  }
138  System.out.println(
139  "Running complete, took " + (System.currentTimeMillis() - start) + " expcted " + getDuration());
140  }
141 
142  private void addWavFileRun(ArrayList<Thread> threads) throws InvalidRemoteException, TransportException,
143  GitAPIException, IOException, UnsupportedAudioFileException, LineUnavailableException {
144 
145  threads.add(new Thread(() -> {
146  try {
147  File path = ScriptingEngine.fileFromGit(getWavurl(), null, // branch
148  getWavfile());
149  AudioInputStream audioStream = AudioSystem.getAudioInputStream(path);
150  Clip audioClip = AudioSystem.getClip();
151  audioClip.addLineListener(event -> {
152  if (LineEvent.Type.STOP.equals(event.getType())) {
153  audioClip.close();
154  }
155  });
156  audioClip.open(audioStream);
157  double len = (double) audioClip.getMicrosecondLength() / 1000.0;
158  if (getDuration() < len)
159  setDuration((long) len);
160  audioClip.start();
161  ThreadUtil.wait(1);
162  try {
163  while (audioClip.isRunning() && !Thread.interrupted()) {
164  double pos = (double) audioClip.getMicrosecondPosition() / 1000.0;
165  double percent = pos / len * 100.0;
166  // System.out.println("Current " + pos + " Percent = " + percent);
167  ThreadUtil.wait(10);
168  }
169  } catch (Throwable t) {
170 
171  }
172  audioClip.stop();
173  audioClip.close();
174  ((AudioInputStream) audioStream).close();
175  System.out.println("Audio clip exited "+getWavurl()+" : "+getWavfile());
176  } catch (Exception e) {
177  e.printStackTrace();
178  }
179 
180  }));
181  }
182 
183  public void load(String content) {
184  setDatabase(gson.fromJson(content, TT_mapStringString));
185  setInitialize(gson.fromJson(gson.toJson(getDatabase().get("initialize")), TT_mapStringString));
186  if (getInitialize() == null)
187  throw new RuntimeException("Cant initialize!");
188  setUrl(getInitialize().get("url").toString());
189  setFile(getInitialize().get("file").toString());
190  setWavurl(getInitialize().get("wavURL").toString());
191  setWavfile(getInitialize().get("wavFile").toString());
192  setDuration(Long.parseLong(getInitialize().get("msDuration").toString()));
193  setDevicesInSequence(gson.fromJson(gson.toJson(getInitialize().get("devices")), TT_listString));
194  for (String key : devicesInSequence) {
195  getSequence(key);
196  }
197  }
198 
199  public HashMap<String, SequenceEvent> getSequence(String d) {
200  String device = getDevice(d);
201  HashMap<String, SequenceEvent> devSeq = gson.fromJson(gson.toJson(getDatabase().get(device)), TT_mapSequence);
202  if (devSeq == null) {
203  devSeq = new HashMap<>();
204  }
205  getDatabase().put(device, devSeq);
206 
207  return devSeq;
208  }
209 
210  private String getDevice(String d) {
211  for (String s : devicesInSequence) {
212  if (s.contentEquals(d))
213  return d;
214  }
215  devicesInSequence.add(d);
216  return d;
217  }
218 
219  public String save() {
220  return gson.toJson(getDatabase());
221  }
222 
223  public ArrayList<String> getDevicesInSequence() {
224  return devicesInSequence;
225  }
226 
227  public void setDevicesInSequence(ArrayList<String> devicesInSequence) {
228  this.devicesInSequence = devicesInSequence;
229  initialize.put("devices", devicesInSequence);
230  }
231 
232  public long getDuration() {
233  return duration;
234  }
235 
236  public void setDuration(long duration) {
237  this.duration = duration;
238  }
239 
240  public String getWavfile() {
241  return wavfile;
242  }
243 
244  public void setWavfile(String wavfile) {
245  this.wavfile = wavfile;
246  }
247 
248  public String getWavurl() {
249  return wavurl;
250  }
251 
252  public void setWavurl(String wavurl) {
253  this.wavurl = wavurl;
254  }
255 
256  public String getFile() {
257  return file;
258  }
259 
260  public void setFile(String file) {
261  this.file = file;
262  }
263 
264  public String getUrl() {
265  return url;
266  }
267 
268  public void setUrl(String url) {
269  this.url = url;
270  }
271 
272  public HashMap<String, Object> getInitialize() {
273  return initialize;
274  }
275 
276  public void setInitialize(HashMap<String, Object> initialize) {
277  this.initialize = initialize;
278  database.put("initialize", initialize);
279  }
280 
281  public HashMap<String, Object> getDatabase() {
282  return database;
283  }
284 
285  public void setDatabase(HashMap<String, Object> database) {
286  this.database = database;
287  }
288 
289 }
static Object gitScriptRun(String gitURL, String Filename)
static File fileFromGit(String remoteURI, String fileInRepo)
static void loadMobileBase(HashMap< String, AbstractKinematicsNR > map, MobileBase specificDevice2, int depth)
void setDevicesInSequence(ArrayList< String > devicesInSequence)
HashMap< String, SequenceEvent > getSequence(String d)
void addWavFileRun(ArrayList< Thread > threads)
void setDatabase(HashMap< String, Object > database)
void setInitialize(HashMap< String, Object > initialize)
static HashMap< String, AbstractKinematicsNR > getDevices()
ArrayList< DHParameterKinematics > getAllDHChains()
ArrayList< DHParameterKinematics > getAllParallelGroups()
static Object getSpecificDevice(String name, IDeviceProvider provider)