BowlerKernel
GcodeDevice.java
Go to the documentation of this file.
1 package com.neuronrobotics.sdk.addons.kinematics.gcodebridge;
2 
3 import java.io.DataInputStream;
4 import java.io.DataOutputStream;
5 import java.io.File;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.OutputStream;
9 import java.io.StringReader;
10 import java.io.StringWriter;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 
14 import com.neuronrobotics.sdk.addons.kinematics.AbstractLink;
15 import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
16 import com.neuronrobotics.sdk.addons.kinematics.LinkType;
17 import com.neuronrobotics.sdk.common.DeviceManager;
18 import com.neuronrobotics.sdk.common.IFlushable;
19 import com.neuronrobotics.sdk.common.Log;
20 import com.neuronrobotics.sdk.common.NonBowlerDevice;
21 import com.neuronrobotics.sdk.util.ThreadUtil;
22 
23 import gnu.io.NRSerialPort;
24 
25 public class GcodeDevice extends NonBowlerDevice implements IGcodeExecuter, IFlushable{
26 
27  private static final String tool = LinkType.GCODE_STEPPER_TOOL.getName();
28 
29  private static final String rot = LinkType.GCODE_STEPPER_ROTORY.getName();
30 
31  private static final String pris = LinkType.GCODE_STEPPER_PRISMATIC.getName();
32 
33  private NRSerialPort serial;
34 
35  private DataInputStream ins=null;
36  private DataOutputStream outs=null;
37  private int timeoutMs = 1000;
39  private HashMap<LinkConfiguration,IGCodeChannel> links = new HashMap<LinkConfiguration,IGCodeChannel>();
40  private AbstractLink heater=null;
41  private AbstractLink bed=null;
42 
43 
44  public GcodeDevice(NRSerialPort serial){
45  this.serial = serial;
46 
47  }
49  String gcodeAxis;
50  switch(axis.getHardwareIndex()){
51  case 0:
52  gcodeAxis=("T");
53  if(heater==null)
54  heater = new GCodeHeater(axis,gcodeAxis,this);
55  return heater;
56  case 1:
57  gcodeAxis=("B");
58  if(bed==null)
59  bed = new GCodeHeater(axis,gcodeAxis,this);
60  return bed;
61  default:
62  throw new RuntimeException("Gcode devices only support 2 heaters");
63  }
64 
65  }
67  if(links.get(axis)!=null)
68  return (AbstractLink)links.get(axis);
69  String gcodeAxis = "";
70  AbstractLink tmp=null;
71  axis.setDeviceTheoreticalMax(Integer.MAX_VALUE);
72  axis.setDeviceTheoreticalMin(Integer.MIN_VALUE);
73  int test =0;
74  if(axis.getTypeString().contentEquals(pris))
75  test=1;
76  if(axis.getTypeString().contentEquals(rot))
77  test=2;
78  if(axis.getTypeString().contentEquals(tool))
79  test=3;
80  switch(test){
81  case 1:
82  case 2:
83  case 3:
84  switch(axis.getHardwareIndex()){
85  case 0:
86  gcodeAxis=("X");
87  break;
88  case 1:
89  gcodeAxis=("Y");
90  break;
91  case 2:
92  gcodeAxis=("Z");
93  break;
94  case 3:
95  gcodeAxis=("E");
96  break;
97  default:
98  throw new RuntimeException("Gcode devices only support 4 axis");
99  }
100  break;
101  default:
102  break;
103  }
104  switch(test){
105  case 1:
106  tmp = new GcodePrismatic(axis,this,gcodeAxis);
107 
108  break;
109  case 2:
110  tmp = new GcodeRotory(axis,this,gcodeAxis);
111 
112  break;
113  case 3:
114  tmp = new GcodeRotory(axis,this,gcodeAxis);
115 
116  break;
117  default:
118  break;
119  }
120  if(tmp!=null){
121  links.put(axis,(IGCodeChannel) tmp);
122  }
123  return tmp;
124  }
125 
126  @Override
127  public void disconnectDeviceImp() {
128  if(serial.isConnected()){
129  runLine("M84");// Disable motors on exit
130  getLine();// fluch buffer
131  }
132  if(outs!=null){
133  try {
134  outs.flush();
135  } catch (IOException e) {
136  // TODO Auto-generated catch block
137  e.printStackTrace();
138  }
139  try {
140  outs.close();
141  } catch (IOException e) {
142  // TODO Auto-generated catch block
143  e.printStackTrace();
144  }
145  }
146  if(ins!=null)
147  try {
148  ins.close();
149  } catch (IOException e) {
150  // TODO Auto-generated catch block
151  e.printStackTrace();
152  }
153  outs=null;
154  ins=null;
155  if(serial.isConnected())
156  serial.disconnect();
157  }
158 
159  @Override
160  public boolean connectDeviceImp() {
162  if(!serial.connect()){
163  throw new RuntimeException("Failed to connect to the serial device");
164  }
165  ins= new DataInputStream(serial.getInputStream());
166  outs = new DataOutputStream(serial.getOutputStream());
167  runLine("M105");// initializes the device
168  return true;
169  }
170 
171  @Override
172  public ArrayList<String> getNamespacesImp() {
173  // TODO Auto-generated method stub
174  return new ArrayList<String>();
175  }
176  @SuppressWarnings("resource")
177  private String getLine(){
178 
179  String ret="";
180  try {
181  if(ins.available()>0){
182  java.util.Scanner s = new java.util.Scanner(ins).useDelimiter("\\A");
183  ret =s.hasNext() ? s.next() : "";
184  }
185  } catch (IOException e) {
186  // TODO Auto-generated catch block
187  e.printStackTrace();
188  }
189  return ret;
190  }
191 
192  //usb.dst contains "1.121.2"
193  @Override
194  public String runLine(String line) {
195  if(!line.endsWith("\r\n"))
196  line = line+"\r\n";
197  try {
198  //synchronized(outs){
199  outs.write(line.getBytes());
200  outs.flush();
201  //}
202  } catch (IOException e) {
203  // TODO Auto-generated catch block
204  e.printStackTrace();
205  }
206  long start = System.currentTimeMillis();
207  String ret= "";
208  while(ret.contentEquals("") &&
209  (System.currentTimeMillis()-start)<getTimeoutMs()){
210 
211  ThreadUtil.wait(10);
212  ret = getLine();
213  }
214  if((System.currentTimeMillis()-start)<getTimeoutMs()){
215  Log.error("GCODE TIMEOUT: "+line);
216  }
217  Log.info("S>>"+line);
218  Log.info("R<<"+ret);
219  return ret;
220  }
221 
222  @Override
223  public void runFile(File gcode) {
224  // TODO Auto-generated method stub
225 
226  }
227 
228  public int getTimeoutMs() {
229  return timeoutMs;
230  }
231 
232  public void setTimeoutMs(int timeoutMs) {
233  this.timeoutMs = timeoutMs;
234  }
235 
236  @Override
238  return config;
239  }
240 
241  @Override
242  public void flush(double seconds) {
243  String run = "G1 ";
244  for(LinkConfiguration l:links.keySet()){
245  IGCodeChannel thisLink = links.get(l);
246  run +=thisLink.getAxis()+""+((AbstractLink)thisLink).getTargetValue()+" ";
247  }
248  loadCurrent();
249  AbstractLink firstLink = (AbstractLink)links.get(links.keySet().toArray()[0]);
250  double distance = firstLink.getTargetValue()-firstLink.getCurrentPosition();
251  if(distance !=0 && seconds>0){
252  int feedrate = (int)Math.abs((distance/(seconds/60)));//mm/min
253  run +=" F"+feedrate;
254  }
255  if(bed!=null)
256  bed.flush(seconds);
257  if(heater!=null)
258  heater.flush(seconds);
259  runLine(run);
260  }
261 
262  public void loadCurrent(){
263  String m114 =runLine("M114");
264  String[] currentPosStr = m114.split("Count")[0].split(" ");// get the current position
265  //System.out.println("Fush with current = "+m114);
266  for(String s:currentPosStr){
267  for(LinkConfiguration l:links.keySet()){
268  IGCodeChannel thisLink = links.get(l);
269  if(s.contains(thisLink.getAxis())){
270  String [] parts = s.split(":");
272  thisLink.setValue(Double.parseDouble(parts[1]));
273  }
274  }
275  }
276  }
277 
278 }
HashMap< LinkConfiguration, IGCodeChannel > links
static void info(String message)
Definition: Log.java:110
static void error(String message)
Definition: Log.java:92