BowlerKernel
CoreScheduler.java
Go to the documentation of this file.
1 package com.neuronrobotics.sdk.dyio.sequencer;
2 
3 import java.io.File;
4 import com.neuronrobotics.sdk.common.Log;
5 import java.io.FileInputStream;
6 import java.io.IOException;
7 import java.util.ArrayList;
8 
9 import javax.xml.parsers.DocumentBuilder;
10 import javax.xml.parsers.DocumentBuilderFactory;
11 import javax.xml.parsers.ParserConfigurationException;
12 
13 import org.w3c.dom.Document;
14 import org.w3c.dom.Element;
15 import org.w3c.dom.Node;
16 import org.w3c.dom.NodeList;
17 import org.xml.sax.SAXException;
18 
19 import com.neuronrobotics.sdk.dyio.DyIO;
20 import com.neuronrobotics.sdk.dyio.peripherals.ServoChannel;
21 import com.neuronrobotics.sdk.util.ThreadUtil;
22 // TODO: Auto-generated Javadoc
23 
29 public class CoreScheduler {
30 
32  private int loopTime;
33 
35  private long flushTime = 0;
36 
38  private SchedulerThread st=null;
39 
41  private SequencerWAV mp3;
42 
44  private boolean loop = false;
45 
47  private ArrayList< ISchedulerListener> listeners = new ArrayList< ISchedulerListener>();
48 
50  private ArrayList< ServoOutputScheduleChannel> outputs = new ArrayList< ServoOutputScheduleChannel>();
51 
53  private DyIO dyio;
54 
56  private String filename=null;
57 
59  private int msDuration=0;
60 
62  //private int trackLength;
63  private File audioFile=null;
64 
66  DyIOFlusher flusher;
67 
69  private long StartOffset;
70 
78  public CoreScheduler(DyIO d, int loopTime,int duration ){
79  setDyIO(d);
80  this.setLoopTime(loopTime);
81  msDuration=duration;
82  }
83 
90  public CoreScheduler(DyIO d, File f){
91  setDyIO(d);
92  loadFromFile(f);
93  }
94 
101  public void loadFromFile(File f){
106  DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
107  DocumentBuilder dBuilder;
108  Document doc = null;
109  try {
110  dBuilder = dbFactory.newDocumentBuilder();
111  doc = dBuilder.parse(new FileInputStream(f));
112  doc.getDocumentElement().normalize();
113  } catch (ParserConfigurationException e) {
114  throw new RuntimeException(e);
115  } catch (SAXException e) {
116  throw new RuntimeException(e);
117  } catch (IOException e) {
118  throw new RuntimeException(e);
119  }
120  //System.out.println("Parsing File...");
121  NodeList nList = doc.getElementsByTagName("ServoOutputSequenceGroup");
122  for (int temp = 0; temp < nList.getLength(); temp++) {
123  //System.out.println("Leg # "+temp);
124  Node nNode = nList.item(temp);
125  if (nNode.getNodeType() == Node.ELEMENT_NODE) {
126  Element eElement = (Element) nNode;
127 
128  String filename = getTagValue("mp3",eElement);
129  if(filename!=null){
130  setAudioFile(new File(filename));
131  }else{
132  msDuration = Integer.parseInt(getTagValue("duration",eElement));
133  }
134  setLoopTime(Integer.parseInt(getTagValue("loopTime",eElement)));
135  NodeList links = eElement.getElementsByTagName("ServoOutputSequence");
136  for (int i = 0; i < links.getLength(); i++) {
137  //System.out.println("\tLink # "+i);
138  Node lNode = links.item(i);
139  if (lNode.getNodeType() == Node.ELEMENT_NODE) {
140  Element lElement = (Element) lNode;
141  int max=Integer.parseInt(getTagValue("outputMax",lElement));
142  int min=Integer.parseInt(getTagValue("outputMin",lElement));
143  int channel=Integer.parseInt(getTagValue("outputChannel",lElement));
144  boolean enabled = getTagValue("inputEnabled",lElement).contains("true");
145 
146  double inScale=Double.parseDouble(getTagValue("inputScale",lElement));
147  int outCenter=Integer.parseInt(getTagValue("outputCenter",lElement));
148  int inChannel=Integer.parseInt(getTagValue("inputChannel",lElement));
149 
150  String [] sdata = getTagValue("data",lElement).split(",");
151  int []data=new int[sdata.length];
152  for(int j=0;j<data.length;j++){
153  data[j]=Integer.parseInt(sdata[j]);
154  }
155  // smooth out and out of place zeros. i should figure out how they keep sneeking in here...
156  for(int j=1;j<data.length-1;j++){
157  int before = data[j-1];
158  int current = data[j];
159  int after = data[j+1];
160  if(current == 0 &&before!=0 && after!=0){
161  System.out.println("Smoothing xml");
162  data[j]=(before+after)/2;
163  }
164  }
166  so.setOutputMinMax(min,max);
167  so.setInputCenter(outCenter);
168  so.setInputScale(inScale);
169  so.setAnalogInputChannelNumber(inChannel);
170  if(!enabled){
171  so.pauseRecording();
172  }else {
173  so.startRecording();
174  }
175  so.setData(data);
176  }
177  }
178 
179  }else{
180  //System.out.println("Not Element Node");
181  }
182  }
183  System.out.println("Populated Scheduler");
184  }
185 
193  private static String getTagValue(String sTag, Element eElement){
194  NodeList nlList= eElement.getElementsByTagName(sTag).item(0).getChildNodes();
195  Node nValue = (Node) nlList.item(0);
196  //System.out.println("\t\t"+sTag+" = "+nValue.getNodeValue());
197  return nValue.getNodeValue();
198  }
199 
205  public void setAudioFile(File f) {
206  if( audioFile==f || f==null)
207  return;
208  audioFile=f;
209  filename=f.getAbsolutePath();
210  mp3 = new SequencerWAV(f.getAbsolutePath());
212  System.out.println("Setting track length: "+msDuration);
214 
215  }
216 
222  public int getTrackLength(){
223  return msDuration;
224  }
225 
231  public void setLooping(boolean b){
232  loop=b;
233  }
234 
240  private boolean isLooping(){
241  return loop;
242  }
243 
249  public boolean isPlaying() {
250  if(getSt() !=null)
251  return !getSt().isPause();
252  return false;
253  }
254 
262  System.out.println("Adding DyIO channel: "+dyIOChannel);
263  ServoChannel srv = new ServoChannel(getDyIO().getChannel(dyIOChannel));
264  srv.SetPosition(srv.getValue());
265  srv.flush();
266  srv.getChannel().setCachedMode(true);
270  //soc.setIntervalTime(loopTime);
271  getOutputs().add(soc);
272  return soc;
273  }
274 
281  getOutputs().remove(s);
282  }
283 
290  public void setSequenceParams(int setpoint,long StartOffset){
291  msDuration=setpoint;
292  this.StartOffset=StartOffset;
293  //System.out.println("Starting scheduler setpoint="+setpoint+" offset="+StartOffset);
294  if(getSt()==null)
296  if(mp3!=null)
298  }
299 
303  public void playStep() {
304  if(getSt()!=null){
305  getSt().playStep();
306  }else{
307  throw new RuntimeException("The sequence paramaters are not set");
308  }
309  }
310 
314  public void play(){
315  mp3.play();
316  getSt().setPause(false);
317  callPlay();
318  ThreadUtil.wait(100);
319  }
320 
327  public void play(int setpoint,long StartOffset) {
328  setSequenceParams( setpoint, StartOffset);
329  play();
330  }
331 
335  public void pause() {
336  if(getSt()!=null)
337  getSt().pause();
338  mp3.pause();
339  callPause();
340  }
341 
349  if(sl==l)
350  return;
351  }
352  listeners.add(l);
353  }
354 
361  listeners.remove(l);
362  }
363 
369  public void setCurrentTime(long time) {
370 
372  s.onTimeUpdate(time);
373  }
374  flusher.setFlush();
376  l.onTimeUpdate(time);
377  }
378 
379  }
380 
384  private void callReset(){
386  l.onReset();
387  }
388  }
389 
393  private void callPause(){
395  l.onPause();
396  }
397  }
398 
402  private void callPlay(){
404  l.onPlay();
405  }
406  }
407 
413  public String getXml(){
414  String s="";
415  s+="<ServoOutputSequenceGroup>\n";
416  if(mp3!=null){
417  s+="\t<mp3>"+filename+"</mp3>\n";
418  }else{
419  s+="\t<duriation>"+msDuration+"</duriation>\n";
420  }
421  s+="\t<loopTime>"+getLoopTime()+"</loopTime>\n";
423  s+=so.getXml();
424  }
425  s+="</ServoOutputSequenceGroup>\n";
426  return s;
427  }
428 
434  public void setOutputs(ArrayList< ServoOutputScheduleChannel> outputs) {
435  this.outputs = outputs;
436  }
437 
443  public ArrayList< ServoOutputScheduleChannel> getOutputs() {
444  return outputs;
445  }
446 
450  private class DyIOFlusher extends Thread{
451 
453  private boolean running = true;
454 
456  private boolean flush = false;
457 
458  /* (non-Javadoc)
459  * @see java.lang.Thread#run()
460  */
461  public void run(){
462  setName("DyIO scheduler flush thread");
463  while(isRunning()){
464  if(isFlush()){
465  flush = false;
466  long start = System.currentTimeMillis();
467  if(getDyIO()!=null){
468  //Log.enableInfoPrint();
469  double seconds =((double)(getLoopTime()))/1000;
471  s.sync((int) seconds);
472  }
473  getDyIO().flushCache(seconds);
474  //Log.enableDebugPrint();
475  }
476  flushTime = System.currentTimeMillis()-start;
477  if(flushTime>getLoopTime()){
478  System.err.println("Flush took:"+flushTime+ " and loop time="+getLoopTime());
480  }
481  }else{
482  try {
483  Thread.sleep(10);
484  } catch (InterruptedException e) {
485  // TODO Auto-generated catch block
486  e.printStackTrace();
487  }
488  }
489  }
490  }
491 
497  public boolean isRunning() {
498  return running;
499  }
500 
504  public void setFlush() {
505  this.flush = true;
506  }
507 
513  public boolean isFlush() {
514  return flush;
515  }
516  }
517 
518 
519 
523  private class SchedulerThread extends Thread{
524 
526  private double time;
527 
529  private boolean run = true;
530 
532  long start = System.currentTimeMillis();
533 
535  private boolean pause = false;
536 
543  public SchedulerThread(double ms,final long so){
544  time = ms;
545  StartOffset=so;
546  //System.out.println("Slider value of init="+StartOffset);
547  if(mp3!=null) {
548  mp3.setCurrentTime((int) (StartOffset));
549  }
551  s.setIntervalTime(getLoopTime(), (int) time);
552  }
553  }
554 
558  public void playStep(){
559  //System.out.println("Stepping scheduler");
560  boolean playing;
561  long current;
562  if(mp3==null){
563 
564  playing = (((double)(System.currentTimeMillis()-start))<(time-StartOffset));
565  current =((System.currentTimeMillis()-start))+StartOffset;
566  }else{
567 
568  playing = mp3.isPlaying();
569  current = mp3.getCurrentTime();
570  }
571  if(!playing){
572  kill();
573  return;
574  }
575 
576  setCurrentTime(current);
577  }
578 
579  /* (non-Javadoc)
580  * @see java.lang.Thread#run()
581  */
582  public void run(){
583  //System.out.println("Starting timer");
584  do{
585  do{
586  while(pause){
587  ThreadUtil.wait(10);
588  }
589 
590  long start = System.currentTimeMillis();
591  playStep();
593  //System.out.println("Flush took "+(System.currentTimeMillis()-start));
594  }while(isRun());
595  setCurrentTime(0);
596  setPause(true);
597  callReset();
598  callPause();
599  }while(true);
600  }
601 
605  public void pause(){
606  if(mp3!=null) {
607  mp3.pause();
608  }
609  setPause(true);
610  }
611 
615  public void kill(){
616  if(mp3!=null) {
617  mp3.pause();
618  }
619  setPause(false);
620  }
621 
627  public boolean isRun() {
628  if(mp3!=null){
629  return run && mp3.isPlaying();
630  }
631  return run;
632  }
633 // public void setRun(boolean run) {
634 // this.run = run;
640 // }
641  public boolean isPause() {
642  return pause;
643  }
644 
650  public void setPause(boolean pause) {
651  this.pause = pause;
652  }
653  }
654 
660  public File getAudioFile() {
661  return audioFile;
662  }
663 
669  public void setDyIO(DyIO dyio) {
670  this.dyio = dyio;
671  flusher = new DyIOFlusher();
672  flusher.start();
673  }
674 
680  public DyIO getDyIO() {
681  return dyio;
682  }
683 
689  public void setLoopTime(int loopTime) {
690  this.loopTime = loopTime;
691  }
692 
698  public int getLoopTime() {
699  return loopTime;
700  }
701 
708  return st;
709  }
710 
716  public void setSt(SchedulerThread st) {
717  this.st = st;
718  st.setPause(true);
719  st.start();
720  }
721 
722 
723 
724 
725 }
void flushCache(double seconds)
Definition: DyIO.java:648
ArrayList< ServoOutputScheduleChannel > outputs
static String getTagValue(String sTag, Element eElement)
void setSequenceParams(int setpoint, long StartOffset)
ArrayList< ServoOutputScheduleChannel > getOutputs()
CoreScheduler(DyIO d, int loopTime, int duration)
ServoOutputScheduleChannel addServoChannel(int dyIOChannel)
void play(int setpoint, long StartOffset)
void setOutputs(ArrayList< ServoOutputScheduleChannel > outputs)
void removeServoOutputScheduleChannel(ServoOutputScheduleChannel s)