BowlerKernel
DyIO.java
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright 2010 Neuron Robotics, LLC
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  ******************************************************************************/
15 package com.neuronrobotics.sdk.dyio;
16 
17 import java.util.ArrayList;
18 
19 import com.neuronrobotics.sdk.commands.bcs.io.AsyncMode;
20 import com.neuronrobotics.sdk.commands.bcs.io.AsyncThreshholdEdgeType;
21 import com.neuronrobotics.sdk.commands.bcs.io.ConfigAsyncCommand;
22 import com.neuronrobotics.sdk.commands.bcs.io.GetChannelModeCommand;
23 import com.neuronrobotics.sdk.commands.bcs.io.GetChannelModeListCommand;
24 import com.neuronrobotics.sdk.commands.bcs.io.GetDyIOChannelCountCommand;
25 import com.neuronrobotics.sdk.commands.bcs.io.SetAllChannelValuesCommand;
26 import com.neuronrobotics.sdk.commands.bcs.io.setmode.SetChannelModeCommand;
27 import com.neuronrobotics.sdk.commands.bcs.pid.DyPID.ConfigureDynamicPIDCommand;
28 import com.neuronrobotics.sdk.commands.bcs.safe.SafeModeCommand;
29 import com.neuronrobotics.sdk.commands.neuronrobotics.dyio.GetAllChannelValuesCommand;
30 import com.neuronrobotics.sdk.commands.neuronrobotics.dyio.PowerCommand;
31 import com.neuronrobotics.sdk.common.BowlerAbstractConnection;
32 import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
33 import com.neuronrobotics.sdk.common.BowlerDatagram;
34 import com.neuronrobotics.sdk.common.BowlerMethod;
35 import com.neuronrobotics.sdk.common.ByteList;
36 import com.neuronrobotics.sdk.common.IConnectionEventListener;
37 import com.neuronrobotics.sdk.common.IFlushable;
38 import com.neuronrobotics.sdk.common.InvalidConnectionException;
39 import com.neuronrobotics.sdk.common.InvalidResponseException;
40 import com.neuronrobotics.sdk.common.Log;
41 import com.neuronrobotics.sdk.common.MACAddress;
42 import com.neuronrobotics.sdk.config.SDKBuildInfo;
43 import com.neuronrobotics.sdk.dyio.dypid.DyPIDConfiguration;
44 import com.neuronrobotics.sdk.namespace.bcs.pid.IPidControlNamespace;
45 import com.neuronrobotics.sdk.pid.GenericPIDDevice;
46 import com.neuronrobotics.sdk.pid.IPIDEventListener;
47 import com.neuronrobotics.sdk.pid.PDVelocityConfiguration;
48 import com.neuronrobotics.sdk.pid.PIDChannel;
49 import com.neuronrobotics.sdk.pid.PIDCommandException;
50 import com.neuronrobotics.sdk.pid.PIDConfiguration;
51 import com.neuronrobotics.sdk.pid.VirtualGenericPIDDevice;
52 import com.neuronrobotics.sdk.util.ThreadUtil;
53 
54 // TODO: Auto-generated Javadoc
61 
63  private static final String NEURONROBOTICS_DYIO_1_0 = "neuronrobotics.dyio.*;1.0";
64 
66  private ArrayList<IDyIOEventListener> listeners = new ArrayList<IDyIOEventListener>();
67 
69  private ArrayList<DyIOChannel> channels = new ArrayList<DyIOChannel>();
70 
72  private byte [] firmware = {0, 0, 0};
73 
75  private String info = "DyIO";
76 
79 
82 
84  private double batteryVoltage = 0;
85 
87  private boolean cachedMode=false;
88 
90  private boolean muteResyncOnModeChange=false;
91 
93  private static boolean checkFirmware=false;
94 
96  private boolean resyncing = false;
97 
99  private boolean haveBeenSynced =false;
100 
102  private boolean legacyParser = false;
103 
105  private Boolean enableBrownOut=null;
106 
113  public DyIO() {
116  }
117 
126  }
127 
138  }
139 
151  }
152 
160  public DyIOChannel getChannel(int channel) {
161  validateChannel(channel);
162  return getInternalChannels().get(channel);
163  }
164 
165  /* (non-Javadoc)
166  * @see com.neuronrobotics.sdk.common.BowlerAbstractDevice#send(java.lang.String, com.neuronrobotics.sdk.common.BowlerMethod, java.lang.String, java.lang.Object[])
167  */
168  public Object[] send(String NS,BowlerMethod method, String rpcString, Object[] arguments){
169  return send(NS,method,rpcString,arguments,2);
170  }
171 
182  public boolean setMode(int channel, DyIOChannelMode mode) {
183  boolean back =getChannel(channel).setMode(mode);
184  //ThreadUtil.wait(200);
185  return back;
186  }
187 
199  public boolean setMode(int channel, DyIOChannelMode mode, boolean async) {
200  return getChannel(channel).setMode(mode, async);
201  }
202 
209  public DyIOChannelMode getMode(int channel) {
210  return getChannel(channel).getMode();
211  }
212 
221  public boolean setValue(int channel, int value) {
222  return getChannel(channel).setValue(value);
223  }
224 
234  public boolean setValue(int channel, ByteList value) {
235  return getChannel(channel).setValue(value);
236  }
245  public boolean setValue(int channel, java.math.BigDecimal value) {
246  return setValue(channel,value.intValue());
247  }
255  public int getValue(int channel) {
256  return getChannel(channel).getValue();
257  }
258 
265  public String getInfo(){
266 // BowlerDatagram response = send(new InfoCommand());
267 // if (response != null) {
268 // info = response.getData().asString();
269 // }
270  return info;
271  }
272 
279  public void setInfo(String info){
280 // if(send(new InfoCommand(info)) == null) {
281 // return;
282 // }
283  this.info = info;
284  }
285 
292  public byte [] getFirmwareRev(){
293  return firmware;
294  }
295 
301  public String getFirmwareRevString(){
302  String revFmt = "%02d.%02d.%03d";
303  return "Firmware Revision: v" + String.format(revFmt, firmware[0], firmware[1], firmware[2]);
304  }
305 
311  public ArrayList<DyIOChannel> getChannels() {
312  ArrayList<DyIOChannel> c = new ArrayList<DyIOChannel>();
313  for(DyIOChannel chan:getInternalChannels() ) {
314  //System.out.println(this.getClass()+" Adding channel: "+chan.getChannelNumber()+" as mode: "+chan.getMode());
315  c.add(chan);
316  }
317  return c;
318  }
319 
326  public void resync(int channel) {
327  getChannel(channel).resync(false);
328  }
329 
334  public static void disableFWCheck() {
335  checkFirmware=false;
336  }
337 
341  public static void enableFWCheck() {
342  //checkFirmware=true;
343  }
344 
354  if(checkFirmware) {
355  int[] sdkRev = SDKBuildInfo.getBuildInfo();
356 
357  for(int i=0;i<3;i++){
358  if(firmware[i] != sdkRev[i]){
359  DyIOFirmwareOutOfDateException e = new DyIOFirmwareOutOfDateException( "\nNRDK version = "+new ByteList(sdkRev)+
360  "\nDyIO version = "+ new ByteList(firmware)+
361  "\nTry updating your firmware using the firmware update instructions from"+
362  "\nhttp://wiki.neuronrobotics.com/NR_Console_Update_Firmware");
363  //e.printStackTrace();
364  throw e;
365  }
366  }
367  }else{
368  Log.info("Not checking firmware version for DyIO");
369  }
370  }
371 
377  public ArrayList<DyIOChannelMode> getAllChannelModes(){
378  ArrayList<DyIOChannelMode> modes = new ArrayList<DyIOChannelMode>();
379  BowlerDatagram response;
380  ByteList bl;
381  if(isLegacyParser()){
382  try {
383  response = send(new GetChannelModeCommand());
384  } catch (Exception e) {
385  if (getInternalChannels().size()==0){
386  Log.error("Initilization failed once, retrying");
387  try{
388  response = send(new GetChannelModeCommand());
389  }catch(Exception e2){
390  e2.printStackTrace();
392  throw new DyIOCommunicationException("DyIO failed to report during initialization. Could not determine DyIO configuration: "+e2.getMessage());
393  }
394  }
395  else {
397  return null;
398  }
399  }
400  if(response == null)
402  //if(getAddress().equals(new MACAddress(MACAddress.BROADCAST))) {
403  setAddress(response.getAddress());
404  //}
405  @SuppressWarnings("unused")
406  int count=0;
407  if(getDyIOChannelCount() != null){
408  count = getDyIOChannelCount();
409  }
410  bl = response.getData();
411 
412  Log.error("Using old parsing model");
413 
414  }else{
415 
416  Object [] args = send("bcs.io.*;0.3;;",
418  "gacm",
419  new Object[]{});
420  bl = (ByteList) args[0];
421  }
422 
423 
424  for (int i = 0; i < bl.size(); i++){
426  modes.add(cm);
427  }
428 
429  return modes;
430  }
431 
432 
441  public boolean resync() {
442  if(getConnection() == null) {
443  Log.info("Not connected");
444  return false;
445  }
446  if(!getConnection().isConnected()) {
447  Log.info("Not connected");
448  return false;
449  }
450  if(isResyncing()) {
451  Log.info("Already resyncing");
452  return true;
453  }
454 
456  setLegacyParser(false);
457  }
458  if(hasNamespace("neuronrobotics.dyio.*;0.3;;")){
459  setLegacyParser(true);
460  }
461  setResyncing(true);
463  Log.info("Re-syncing...");
464  getBatteryVoltage(true);
465  BowlerDatagram response;
466  try{
467  if (!haveFirmware()){
468 
469  firmware = getRevisions().get(0).getBytes();
470  }
472 // if(info.contains("Unknown")){
473 // response = send(new InfoCommand());
474 // if (response != null) {
475 // info = response.getData().asString();
476 // }
477 // }
478 
479  }catch (Exception e){
480  e.printStackTrace();
482  }
483 
484  ArrayList<DyIOChannelMode> modes = getAllChannelModes();
485 
486  for (int i = 0; i < modes.size(); i++){
487  DyIOChannelMode cm = modes.get(i);
488  boolean editable = true;
489  if(cm == null) {
491  editable = false;
492  try {
493  Log.error("Mode get failed, setting to default");
494  send(new SetChannelModeCommand(i, cm));
495  } catch(Exception e) {
497  throw new DyIOCommunicationException("Setting a pin to Digital In failed");
498  }
499  }
500  try{
501  Log.info("\n\nUpdating channel: "+i);
502  getInternalChannels().get(i).update(this, i, cm, editable);
503  }catch(IndexOutOfBoundsException e){
504  //System.out.println("New channel "+i);
505  getInternalChannels().add(new DyIOChannel(this, i, cm, editable));
506  DyIOChannel dc =getInternalChannels().get(i);
508  }
509  }
510 
512  if (getInternalChannels().size()==0)
513  throw new DyIOCommunicationException("DyIO failed to report during initialization");
514 
515  haveBeenSynced =true;
516  setResyncing(false);
517  return true;
518  }
519 
525  private boolean haveFirmware() {
526  if (firmware[0]==0 && firmware[1]==0 && firmware[2]==0)
527  return false;
528  else
529  return true;
530  }
531 
544  if(listeners.contains(l)) {
545  return;
546  }
547 
548  listeners.add(l);
549  }
550 
558  if(!listeners.contains(l)) {
559  return;
560  }
561 
562  listeners.remove(l);
563  }
564 
569  listeners.clear();
570  }
571 
578  public void fireDyIOEvent(IDyIOEvent e) {
579  //System.out.println("DyIO Event: "+e);
580  for(IDyIOEventListener l : listeners) {
581  l.onDyIOEvent(e);
582  }
583  }
584 
590  protected void validateChannel(int channel) {
591  int syncs=0;
592 // while(isResyncing()){
593 // ThreadUtil.wait(100);
594 // }
595  if(!haveBeenSynced)
596  return;
597  while(getInternalChannels().size() == 0){
598  Log.error("Valadate will fail, no channels, resyncing");
599  resync();
600  syncs++;
601  if(syncs>5){
602  throw new DyIOCommunicationException("DyIO failed to report number of channels");
603  }
604  ThreadUtil.wait(200);
605 
606  }
607  if (channel < 0 || channel > getInternalChannels().size()) {
608  throw new IndexOutOfBoundsException("DyIO channels must be between 0 and " + getInternalChannels().size()+" requested:"+channel);
609  }
610  }
611 
612 
613 
618  public boolean getCachedMode() {
619  return cachedMode;
620  }
628  public void setCachedMode(boolean mode) {
629  cachedMode=mode;
631  d.setCachedMode(mode);
632  if(mode)
633  try {
634  d.setCachedValue(d.getValue());
635  }catch(Exception e){
636  d.setCachedValue(128);
637  }
638  }
639  }
640 
648  public void flushCache(double seconds) {
649  //System.out.println("Updating all channels");
650  Integer [] values = new Integer[getInternalChannels().size()];
651  int i=0;
653  values[i++]=d.getCachedValue();
654  //System.out.println("Flushing chan "+d+" to "+d.getCachedValue());
655  }
656  if(isLegacyParser()){
657  for(int j=0;j<5;j++) {
658  try {
659  send(new SetAllChannelValuesCommand(seconds,values));
660  return;
661  }catch (InvalidResponseException e1) {
662  System.err.println("Failed to update all, retrying");
663  }
664  }
665  }else{
666 // for(DyIOChannel d:getInternalChannels()) {
667 // d.setCachedTime((float) seconds);
668 // if(d.getMode()==DyIOChannelMode.SERVO_OUT)
669 // d.flush();
670 // }
671  send("bcs.io.*;0.3;;",
673  "sacv",
674  new Object[]{new Integer((int) (seconds*1000)),values});
675 
676  }
677 
678  }
679 
680 
681  /* (non-Javadoc)
682  * @see com.neuronrobotics.sdk.common.BowlerAbstractDevice#isAvailable()
683  */
684  public boolean isAvailable() throws InvalidConnectionException {
685  if(getConnection() == null)
686  return false;
687  return getConnection().isConnected();
688 
689  }
690 // /* (non-Javadoc)
691 // * @see com.neuronrobotics.sdk.common.IBowlerDatagramListener#onAllResponse(com.neuronrobotics.sdk.common.BowlerDatagram)
692 // */
693 // public void onAllResponse(BowlerDatagram data) {
694 //
695 // getPid().onAllResponse(data);
696 // }
697 //
705  return bankAState;
706  }
707 
715  return bankBState;
716  }
717 
723  public double getBatteryVoltage(boolean refresh){
724  if(refresh) {
725  BowlerDatagram data = send(new PowerCommand());
726  powerEvent(data);
727  }
728  return batteryVoltage;
729  }
730 
736  private void powerEvent(BowlerDatagram data) {
737 
738  //Log.warning("POWER event "+data);
739  if(data.getRPC().contains("_pwr")){
740  ByteList bl = data.getData();
741  if(isLegacyParser() && bl.size() == 1){
742  enableBrownOut=bl.get(0)!=0;
743  }
744  if(bl.size()> 1){
745  batteryVoltage = ((double)(ByteList.convertToInt(bl.getBytes(2, 2),false)))/1000.0;
748  if(!isLegacyParser()){
749  enableBrownOut=bl.get(4)!=0;
750  }
751  }
753  return;
754  }else{
755  Log.error("Wrong type for updating Power state "+data);
756  }
757  }
758 
759  /* (non-Javadoc)
760  * @see com.neuronrobotics.sdk.common.IBowlerDatagramListener#onAsyncResponse
761  */
762  public void onAsyncResponse(BowlerDatagram data) {
763  if(!haveBeenSynced){
764  return;
765  }
766  Log.info("<< Async\n"+data.toString());
767  if(data.getRPC().equals("_pwr")) {
768 
769  powerEvent(data);
770  }
771  if(data.getRPC().equals("gchv")) {
772  ByteList bl = data.getData();
773 
774  Byte b = bl.pop();
775  if(b == null) {
776  return;
777  }
778  DyIOChannel c = getChannel(b);
779  c.fireChannelEvent(new DyIOChannelEvent(c, bl));
780  return;
781  }if(data.getRPC().equals("gacv")) {
782 
783  if(isLegacyParser()){
784  Log.error("All channel values\n"+data.toString());
785  ByteList bl = data.getData();
786  for(DyIOChannel c:getChannels()){
787  ByteList val = new ByteList(bl.popList(4));
788  Log.error("DyIO event "+c+" value: "+val);
789  if(!c.isStreamChannel())
790  c.fireChannelEvent(new DyIOChannelEvent(c,val));
791  }
792  }else{
793  Log.info("All channel values\n"+data.toString());
794  ByteList bl = data.getData();
795  int numChan = bl.pop();
796  if(numChan !=getChannels().size() ){
797  Log.error("Bad packet, wrong number of values");
798  }
799  for(int i=0;i<getChannels().size();i++){
800  DyIOChannel c= getChannels().get(i);
801  ByteList val = new ByteList(bl.popList(4));
802  Log.info("DyIO event "+c+" value: "+val);
803  if(!c.isStreamChannel())
804  c.fireChannelEvent(new DyIOChannelEvent(c,val));
805  }
806  }
807 
808  }if(data.getRPC().equals("strm")) {
809  Log.warning("STREAM Packet\n"+data.toString());
810  ByteList bl = data.getData();
811 
812  Byte b = bl.pop();// channel value
813  if(b == null) {
814  return;
815  }
816  bl.pop();// size of array
817  DyIOChannel c = getChannel(b);
818  c.fireChannelEvent(new DyIOChannelEvent(c, bl));
819  }else{
820  IDyIOEvent e = new DyIOAsyncEvent(data);
821  fireDyIOEvent(e);
822  }
823 
824 
825  getPid().onAsyncResponse(data);
826  }
827 
828 
838  return send(new ConfigureDynamicPIDCommand(config))!=null;
839  }
840 
848  BowlerDatagram conf = send(new ConfigureDynamicPIDCommand( group) );
849  DyPIDConfiguration back=new DyPIDConfiguration(conf);
850  return back;
851  }
852 
853 
854  /* (non-Javadoc)
855  * @see com.neuronrobotics.sdk.pid.IPIDControl#ResetPIDChannel
856  */
857  public boolean ResetPIDChannel(int group, float valueToSetCurrentTo) {
858  return getPid().ResetPIDChannel(group, valueToSetCurrentTo);
859  }
860 
867  /* (non-Javadoc)
868  * @see com.neuronrobotics.sdk.pid.IPIDControl#ResetPIDChannel
869  */
870  public boolean ResetPIDChannel(int group) {
871  return getPid().ResetPIDChannel(group,0);
872  }
873  /* (non-Javadoc)
874  * @see com.neuronrobotics.sdk.pid.IPIDControl#SetPIDSetPoint
875  */
876  public boolean SetPIDSetPoint(int group,float setpoint, double seconds){
877  return getPid().SetPIDSetPoint(group, setpoint,seconds);
878  }
879  /* (non-Javadoc)
880  * @see com.neuronrobotics.sdk.pid.IPIDControl#SetAllPIDSetPoint
881  */
882  public boolean SetAllPIDSetPoint(float []setpoints, double seconds){
883  return getPid().SetAllPIDSetPoint(setpoints,seconds);
884  }
885  /* (non-Javadoc)
886  * @see com.neuronrobotics.sdk.pid.IPIDControl#GetPIDPosition
887  */
888  public float GetPIDPosition(int group) {
889  return getPid().GetPIDPosition(group);
890  }
891  /* (non-Javadoc)
892  * @see com.neuronrobotics.sdk.pid.IPIDControl#GetAllPIDPosition
893  */
894  public float [] GetAllPIDPosition() {
895  return getPid().GetAllPIDPosition();
896  }
897  /* (non-Javadoc)
898  * @see com.neuronrobotics.sdk.pid.IPIDControl#ConfigurePIDController
899  */
900  public boolean ConfigurePIDController(PIDConfiguration config) {
901  return getPid().ConfigurePIDController(config);
902  }
903  /* (non-Javadoc)
904  * @see com.neuronrobotics.sdk.pid.IPIDControl#getPIDConfiguration
905  */
907  return getPid().getPIDConfiguration(group);
908  }
909  /* (non-Javadoc)
910  * @see com.neuronrobotics.sdk.pid.IPIDControl#addPIDEventListener
911  */
914  }
915  /* (non-Javadoc)
916  * @see com.neuronrobotics.sdk.pid.IPIDControl#removePIDEventListener
917  */
920  }
921  /* (non-Javadoc)
922  * @see com.neuronrobotics.sdk.pid.IPIDControl#flushPIDChannels
923  */
924  @Override
925  public void flushPIDChannels(double time) {
926  getPid().flushPIDChannels(time);
927  }
928  /* (non-Javadoc)
929  * @see com.neuronrobotics.sdk.pid.IPIDControl#getPIDChannel
930  */
931  @Override
932  public PIDChannel getPIDChannel(int group) {
933  return getPid().getPIDChannel(group);
934 
935  }
936  /* (non-Javadoc)
937  * @see com.neuronrobotics.sdk.pid.IPIDControl#SetPIDInterpolatedVelocity
938  */
939  @Override
940  public boolean SetPIDInterpolatedVelocity(int group, int unitsPerSecond, double seconds) throws PIDCommandException {
941  return getPid().SetPIDInterpolatedVelocity(group, unitsPerSecond, seconds);
942  }
943  /* (non-Javadoc)
944  * @see com.neuronrobotics.sdk.pid.IPIDControl#SetPDVelocity
945  */
946  @Override
947  public boolean SetPDVelocity(int group, int unitsPerSecond, double seconds)throws PIDCommandException {
948  return getPid().SetPDVelocity(group, unitsPerSecond, seconds);
949  }
950  /* (non-Javadoc)
951  * @see com.neuronrobotics.sdk.pid.IPIDControl#killAllPidGroups
952  */
953  @Override
954  public boolean killAllPidGroups() {
955  return getPid().killAllPidGroups();
956  }
957 
958  /*
959  * Advanced Async Configuration. THese methods configure what value changes trigger an asynchronous event as well as
960  * how often those event states are checked
961  */
968  public boolean configAdvancedAsyncNotEqual(int pin){
969  return configAdvancedAsyncNotEqual(pin,100);
970  }
971 
980  public boolean configAdvancedAsyncDeadBand(int pin,int deadbandSize){
981  return configAdvancedAsyncDeadBand(pin,100,deadbandSize);
982  }
983 
993  public boolean configAdvancedAsyncTreshhold(int pin,int threshholdValue, AsyncThreshholdEdgeType edgeType){
994  return configAdvancedAsyncTreshhold(pin,100, threshholdValue, edgeType);
995  }
996 
1005  public boolean configAdvancedAsyncAutoSample(int pin){
1006  return configAdvancedAsyncAutoSample(pin,100);
1007  }
1008 
1015  public boolean configAdvancedAsyncNotEqual(int pin,int time){
1016  return send(new ConfigAsyncCommand(pin,time,AsyncMode.NOTEQUAL)) == null;
1017  }
1018 
1027  public boolean configAdvancedAsyncDeadBand(int pin,int time,int deadbandSize){
1028  return send(new ConfigAsyncCommand(pin,time,deadbandSize)) == null;
1029  }
1030 
1040  public boolean configAdvancedAsyncTreshhold(int pin,int time,int threshholdValue, AsyncThreshholdEdgeType edgeType){
1041  return send(new ConfigAsyncCommand(pin,time,threshholdValue,edgeType)) == null;
1042  }
1043 
1052  public boolean configAdvancedAsyncAutoSample(int pin,int time){
1053  return send(new ConfigAsyncCommand(pin,time,AsyncMode.AUTOSAMP)) == null;
1054  }
1055 
1056 
1057 
1058  /* (non-Javadoc)
1059  * @see com.neuronrobotics.sdk.common.BowlerAbstractDevice#connect()
1060  */
1061  public boolean connect(){
1062  if(getConnection()!=null) {
1065  }
1066  if(super.connect()) {
1067  if(getConnection().hasNamespace("bcs.pid.*;1.0;;", getAddress())){
1070  getPid().connect();
1071  }else{
1072  pid=new VirtualGenericPIDDevice("DyIO VirtualDevice");
1073  }
1074 
1075 
1076  send( new PowerCommand());
1077  startHeartBeat(3000);
1078  resync();
1079  return true;
1080  }
1081  return false;
1082  }
1083 
1092  public void startHeartBeat(long msHeartBeatTime){
1093  super.startHeartBeat(msHeartBeatTime);
1094  try{
1095  BowlerDatagram b = send(new SafeModeCommand(true, (int) msHeartBeatTime));
1096  if(b== null)
1097  checkFirmwareRev();
1098  }catch(Exception e){
1099  System.err.println("DyIO is out of date");
1100  checkFirmwareRev();
1101  }
1102  }
1103 
1109  public int getHeartBeatTime(){
1110  BowlerDatagram b = send(new SafeModeCommand());
1111  if(b==null)
1112  return 0;
1113  return ByteList.convertToInt(b.getData().getBytes(1, 2));
1114  }
1115 
1119  public void stopHeartBeat(){
1120 
1121  super.stopHeartBeat();
1122  try{
1123  BowlerDatagram b = send(new SafeModeCommand(false, 0));
1124  if(b== null)
1125  checkFirmwareRev();
1126  }catch(Exception e){
1127  System.err.println("DyIO is out of date");
1128  checkFirmwareRev();
1129  }
1130  }
1131 
1132 
1133 // /**
1134 // * This method allows you to disable the brown out detect for the servo subsystem. If true is passed
1135 // * @param enable true to enable the borwnout, false to disable
1136 // * @return True is success
1137 // */
1138 // @Deprecated
1139 // public boolean enableBrownOutDetect(boolean enable) {
1140 // return setServoPowerSafeMode(enable);
1141 // }
1142 // /**
1143 // * Tells the application whether or not to use the brownout detect
1144 // * @return
1145 // */
1146 // @Deprecated
1147 // public boolean isBrownOutDetectEnabled() {
1148 // return isServoPowerSafeMode();
1149 // }
1150 
1156  public boolean setServoPowerSafeMode(boolean enable) {
1157  enableBrownOut=enable;
1159  return true;
1160  }
1161 
1167  public Boolean isServoPowerSafeMode() {
1168  if(enableBrownOut== null){
1169  setServoPowerSafeMode(true);
1170  }
1171  return enableBrownOut;
1172  }
1173 
1179  private ArrayList<DyIOChannel> getInternalChannels() {
1180  return channels;
1181  }
1182 
1188  this.muteResyncOnModeChange = muteResyncOnModeChange;
1189  }
1190 
1196  public boolean isMuteResyncOnModeChange() {
1197  return muteResyncOnModeChange;
1198  }
1199 
1200  /* (non-Javadoc)
1201  * @see com.neuronrobotics.sdk.common.IConnectionEventListener#onDisconnect(com.neuronrobotics.sdk.common.BowlerAbstractConnection)
1202  */
1203  @Override
1205  firmware[0]=0;
1206  firmware[1]=0;
1207  firmware[2]=0;
1208  }
1209 
1210  /* (non-Javadoc)
1211  * @see com.neuronrobotics.sdk.common.IConnectionEventListener#onConnect(com.neuronrobotics.sdk.common.BowlerAbstractConnection)
1212  */
1213  @Override
1214  public void onConnect(BowlerAbstractConnection source) {
1215 
1216  }
1217 
1223  public void setResyncing(boolean resyncing) {
1224  this.resyncing = resyncing;
1225  }
1226 
1232  public boolean isResyncing() {
1233  return resyncing;
1234  }
1235 
1236 
1237  /* (non-Javadoc)
1238  * @see java.lang.Object#toString()
1239  */
1240 
1241  public String toString() {
1242 
1243  String chFmt = "%02d - ( %04d ) - %-20s %02d - ( %04d ) - %-20s\n";
1244 
1245  String s = getFirmwareRevString()+ " \nMAC: " + getAddress() + "\n";
1246  for(int i = 0; i < getInternalChannels().size()/2; i++) {
1247  int oppisite=getInternalChannels().size()-1-i;
1248  s += String.format(chFmt,
1249  oppisite,
1250  getInternalChannels().get(oppisite).getPreviousValue(),
1251  getInternalChannels().get(oppisite).getMode().toSlug(),
1252 
1253  i,
1254  getInternalChannels().get(i).getPreviousValue(),
1255  getInternalChannels().get(i).getMode().toSlug()
1256  );
1257  }
1258 
1259  return s;
1260  }
1261 
1267  public int[] getAllChannelValues() {
1268  int [] back = new int[getInternalChannels().size()];
1269  if(isLegacyParser()){
1271  Log.info("GACV RX<<\n"+gacv);
1272  ByteList bl = gacv.getData();
1273  int i=0;
1274  for(DyIOChannel c:getChannels()){
1275  if(!c.isStreamChannel()){
1276  ByteList val = new ByteList(bl.popList(4));
1277  DyIOChannelEvent ev =new DyIOChannelEvent(c,val);
1278  back[i++]=ev.getValue();
1279  if(!c.isStreamChannel()){
1280  c.fireChannelEvent(ev);
1281  }
1282  }else{
1283  back[i++] = 0;
1284  }
1285  }
1286  }else{
1287  //Log.enableInfoPrint();
1288  Object [] args = send("bcs.io.*;0.3;;",
1289  BowlerMethod.GET,
1290  "gacv",
1291  new Object[]{});
1292  Integer [] values = (Integer [])args[0];
1293  for(int i=0;i<getChannels().size();i++){
1294  DyIOChannel c =getChannels().get(i);
1295  if(!c.isStreamChannel()){
1296  DyIOChannelEvent ev =new DyIOChannelEvent(c,values[i]);
1297  back[i]=values[i];
1298  if(!c.isStreamChannel()){
1299  c.fireChannelEvent(ev);
1300  }
1301  }
1302  }
1303  }
1304 
1305  return back;
1306  }
1307 
1308  /* (non-Javadoc)
1309  * @see com.neuronrobotics.sdk.namespace.bcs.pid.IPidControlNamespace#ConfigurePDVelovityController(com.neuronrobotics.sdk.pid.PDVelocityConfiguration)
1310  */
1311  @Override
1313  // TODO Auto-generated method stub
1314  return getPid().ConfigurePDVelovityController(config);
1315  }
1316 
1317  /* (non-Javadoc)
1318  * @see com.neuronrobotics.sdk.namespace.bcs.pid.IPidControlNamespace#getPDVelocityConfiguration(int)
1319  */
1320  @Override
1322  // TODO Auto-generated method stub
1323  return getPid().getPDVelocityConfiguration(group);
1324  }
1325 
1326  /* (non-Javadoc)
1327  * @see com.neuronrobotics.sdk.namespace.bcs.pid.IPidControlNamespace#getPIDChannelCount()
1328  */
1329  @Override
1330  public int getPIDChannelCount() {
1331  // TODO Auto-generated method stub
1332  return getPid().getPIDChannelCount();
1333  }
1334 
1336  private Integer dyioChanCount = null;
1337 
1343  public Integer getDyIOChannelCount(){
1344 
1345  if(dyioChanCount == null){
1346  if(isLegacyParser()){
1347  try{
1350  }catch(InvalidResponseException ex){
1351  ex.printStackTrace();
1352  }
1353  }else{
1354  Object [] args = send("bcs.io.*;0.3;;",
1355  BowlerMethod.GET,
1356  "gchc",
1357  new Object[]{});
1358  dyioChanCount = (Integer)args[0];
1359  }
1360  }
1361  return dyioChanCount;
1362  }
1363 
1370  public ArrayList<DyIOChannelMode> getAvailibleChannelModes(int channel){
1371  ArrayList<DyIOChannelMode> modes = new ArrayList<DyIOChannelMode>();
1372  ByteList m;
1373 
1374  if(isLegacyParser()){
1375  BowlerDatagram dg = send(new GetChannelModeListCommand(channel));
1376  m = dg.getData();
1377  Log.error("Packet "+channel+"\r\n"+dg);
1378  Log.error("Data: "+channel+"\r\n"+m);
1379 
1380  }else{
1381  //int l = Log.getMinimumPrintLevel();
1382  //Log.enableInfoPrint();
1383  Object [] args = send("bcs.io.*;0.3;;",
1384  BowlerMethod.GET,
1385  "gcml",
1386  new Object[]{channel});
1387  m = (ByteList)args[0];
1388  //Log.setMinimumPrintLevel(l);
1389  }
1390  String modeString = " Availible modes on "+channel;
1391  for(int i=0;i<m.size();i++){
1392  DyIOChannelMode tmpMode = DyIOChannelMode.get(m.getByte(i));
1393  modeString +="\r\n\t"+tmpMode.toString()+"\r\n\t";
1394  modes.add(tmpMode);
1395  }
1396  Log.info(modeString);
1397  return modes;
1398  }
1399 
1406  return pid;
1407  }
1408 
1414  public boolean isLegacyParser() {
1415  return legacyParser;
1416  }
1417 
1423  public void setLegacyParser(boolean legacyParser) {
1424  this.legacyParser = legacyParser;
1425  }
1426 
1427  @Override
1428  public void flush(double seconds) {
1429  flushCache(seconds);
1430  }
1431 
1432 }
void setConnection(BowlerAbstractConnection connection)
static final int convertToInt(byte[] b)
Definition: ByteList.java:911
static void info(String message)
Definition: Log.java:110
static void error(String message)
Definition: Log.java:92
static void warning(String message)
Definition: Log.java:101
boolean setMode(DyIOChannelMode mode)
void fireModeChangeEvent(DyIOChannelMode e)
void fireChannelEvent(DyIOChannelEvent e)
DyIOChannelMode getMode(boolean resync)
void validateChannel(int channel)
Definition: DyIO.java:590
boolean configAdvancedAsyncDeadBand(int pin, int deadbandSize)
Definition: DyIO.java:980
boolean setValue(int channel, int value)
Definition: DyIO.java:221
void flush(double seconds)
Definition: DyIO.java:1428
DyIO(BowlerAbstractConnection connection)
Definition: DyIO.java:133
ArrayList< DyIOChannel > channels
Definition: DyIO.java:69
boolean setServoPowerSafeMode(boolean enable)
Definition: DyIO.java:1156
boolean ResetPIDChannel(int group)
Definition: DyIO.java:870
void removePIDEventListener(IPIDEventListener l)
Definition: DyIO.java:918
void setCachedMode(boolean mode)
Definition: DyIO.java:628
DyIO(MACAddress address, BowlerAbstractConnection connection)
Definition: DyIO.java:146
DyIOPowerState getBankBState()
Definition: DyIO.java:714
ArrayList< DyIOChannelMode > getAvailibleChannelModes(int channel)
Definition: DyIO.java:1370
ArrayList< DyIOChannel > getInternalChannels()
Definition: DyIO.java:1179
void setInfo(String info)
Definition: DyIO.java:279
void setMuteResyncOnModeChange(boolean muteResyncOnModeChange)
Definition: DyIO.java:1187
DyIOPowerState getBankAState()
Definition: DyIO.java:704
float GetPIDPosition(int group)
Definition: DyIO.java:888
DyPIDConfiguration getDyPIDConfiguration(int group)
Definition: DyIO.java:847
boolean ConfigurePIDController(PIDConfiguration config)
Definition: DyIO.java:900
ArrayList< IDyIOEventListener > listeners
Definition: DyIO.java:66
boolean SetPIDSetPoint(int group, float setpoint, double seconds)
Definition: DyIO.java:876
Object[] send(String NS, BowlerMethod method, String rpcString, Object[] arguments)
Definition: DyIO.java:168
DyIOChannelMode getMode(int channel)
Definition: DyIO.java:209
boolean ResetPIDChannel(int group, float valueToSetCurrentTo)
Definition: DyIO.java:857
DyIOPowerState bankBState
Definition: DyIO.java:81
ArrayList< DyIOChannel > getChannels()
Definition: DyIO.java:311
void removeDyIOEventListener(IDyIOEventListener l)
Definition: DyIO.java:557
static final String NEURONROBOTICS_DYIO_1_0
Definition: DyIO.java:63
void onAsyncResponse(BowlerDatagram data)
Definition: DyIO.java:762
void startHeartBeat(long msHeartBeatTime)
Definition: DyIO.java:1092
void flushPIDChannels(double time)
Definition: DyIO.java:925
boolean configAdvancedAsyncAutoSample(int pin)
Definition: DyIO.java:1005
int getValue(int channel)
Definition: DyIO.java:255
static void disableFWCheck()
Definition: DyIO.java:334
boolean setValue(int channel, java.math.BigDecimal value)
Definition: DyIO.java:245
boolean configAdvancedAsyncTreshhold(int pin, int threshholdValue, AsyncThreshholdEdgeType edgeType)
Definition: DyIO.java:993
boolean ConfigurePDVelovityController(PDVelocityConfiguration config)
Definition: DyIO.java:1312
void onConnect(BowlerAbstractConnection source)
Definition: DyIO.java:1214
PDVelocityConfiguration getPDVelocityConfiguration(int group)
Definition: DyIO.java:1321
void addDyIOEventListener(IDyIOEventListener l)
Definition: DyIO.java:543
ArrayList< DyIOChannelMode > getAllChannelModes()
Definition: DyIO.java:377
static boolean checkFirmware
Definition: DyIO.java:93
void setResyncing(boolean resyncing)
Definition: DyIO.java:1223
void onDisconnect(BowlerAbstractConnection source)
Definition: DyIO.java:1204
boolean ConfigureDynamicPIDChannels(DyPIDConfiguration config)
Definition: DyIO.java:837
boolean SetPIDInterpolatedVelocity(int group, int unitsPerSecond, double seconds)
Definition: DyIO.java:940
void powerEvent(BowlerDatagram data)
Definition: DyIO.java:736
void fireDyIOEvent(IDyIOEvent e)
Definition: DyIO.java:578
void flushCache(double seconds)
Definition: DyIO.java:648
boolean configAdvancedAsyncNotEqual(int pin, int time)
Definition: DyIO.java:1015
DyIOPowerState bankAState
Definition: DyIO.java:78
void setLegacyParser(boolean legacyParser)
Definition: DyIO.java:1423
boolean configAdvancedAsyncTreshhold(int pin, int time, int threshholdValue, AsyncThreshholdEdgeType edgeType)
Definition: DyIO.java:1040
boolean setValue(int channel, ByteList value)
Definition: DyIO.java:234
void resync(int channel)
Definition: DyIO.java:326
boolean setMode(int channel, DyIOChannelMode mode, boolean async)
Definition: DyIO.java:199
PIDChannel getPIDChannel(int group)
Definition: DyIO.java:932
boolean configAdvancedAsyncDeadBand(int pin, int time, int deadbandSize)
Definition: DyIO.java:1027
double getBatteryVoltage(boolean refresh)
Definition: DyIO.java:723
PIDConfiguration getPIDConfiguration(int group)
Definition: DyIO.java:906
void addPIDEventListener(IPIDEventListener l)
Definition: DyIO.java:912
boolean setMode(int channel, DyIOChannelMode mode)
Definition: DyIO.java:182
boolean configAdvancedAsyncNotEqual(int pin)
Definition: DyIO.java:968
boolean SetAllPIDSetPoint(float[]setpoints, double seconds)
Definition: DyIO.java:882
boolean configAdvancedAsyncAutoSample(int pin, int time)
Definition: DyIO.java:1052
boolean SetPDVelocity(int group, int unitsPerSecond, double seconds)
Definition: DyIO.java:947
DyIOChannel getChannel(int channel)
Definition: DyIO.java:160
DyIO(MACAddress address)
Definition: DyIO.java:123
GenericPIDDevice getPid()
Definition: DyIO.java:1405
boolean ConfigurePDVelovityController(PDVelocityConfiguration config)
boolean SetAllPIDSetPoint(float[] setpoints, double seconds)
boolean ResetPIDChannel(int group, float valueToSetCurrentTo)
boolean SetPDVelocity(int group, int unitsPerSecond, double seconds)
PDVelocityConfiguration getPDVelocityConfiguration(int group)
PIDConfiguration getPIDConfiguration(int group)
boolean SetPIDSetPoint(int group, float setpoint, double seconds)
boolean ConfigurePIDController(PIDConfiguration config)
void setConnection(BowlerAbstractConnection connection)
boolean SetPIDInterpolatedVelocity(int group, int unitsPerSecond, double seconds)
static DyIOChannelMode get(byte code)
static DyIOPowerState valueOf(int code, double batteryVoltage)