Browse Source

Checkpoint

motorcontrol
Tim Schuster 2 years ago
parent
commit
971c750149
Signed by: Tim Schuster <mail@timschuster.info> GPG Key ID: F9E27097EFB77F61

+ 26
- 3
chc.go View File

@@ -6,6 +6,7 @@ import (
6 6
 	"log"
7 7
 	"os"
8 8
 	"github.com/pkg/errors"
9
+	"strings"
9 10
 )
10 11
 
11 12
 func init() {
@@ -20,17 +21,21 @@ func init() {
20 21
 	helpm["rotate"] = "Rotates the head. [angle]"
21 22
 
22 23
 	cmds["connect"] = connect
23
-	helpm["connect"] = "Connects to a Hardware Controller"
24
+	helpm["connect"] = "Connects to a Hardware Controller. [path]"
25
+
26
+	cmds["deliver"] = deliver
27
+	helpm["deliver"] = "Delivers item from reg=Column fch=Row. [reg,fch]"
24 28
 }
25 29
 
26 30
 func connect(params []string) error {
27 31
 	var path string
28 32
 
29 33
 	for k := range params {
30
-		if err := parseParamToString("cfg", &path, params[k]); err != nil {
31
-			return errors.Wrap(err, "Error while parsing Config Path")
34
+		if strings.HasPrefix(params[k],"path=") {
35
+			path = strings.TrimPrefix(params[k], "path=")
32 36
 		}
33 37
 	}
38
+	fmt.Printf("Using Config Path %s\n", path)
34 39
 	logger := log.New(os.Stderr, "CHC", log.Lshortfile | log.LUTC)
35 40
 	hc := HardwareControl.NewHardwareControl(logger, path)
36 41
 	curCHC = hc
@@ -114,3 +119,21 @@ func rotate(params []string) error {
114 119
 	curCHC.Rotate(angle)
115 120
 	return nil
116 121
 }
122
+
123
+func deliver(params []string) error {
124
+	var (
125
+		regalNumber, fachNumber int32
126
+	)
127
+
128
+	for k := range params {
129
+		if err := parseParamToInt32("reg", &regalNumber, params[k]); err != nil {
130
+			return errors.Wrap(err, "Error while parsing hspd")
131
+		}
132
+		if err := parseParamToInt32("fch", &fachNumber, params[k]); err != nil {
133
+			return errors.Wrap(err, "Error while parsing vspd")
134
+		}
135
+	}
136
+
137
+	curCHC.Deliver(regalNumber, fachNumber)
138
+	return nil
139
+}

+ 110
- 6
direct.go View File

@@ -1,10 +1,114 @@
1 1
 package chocococon
2 2
 
3
+import (
4
+	"fmt"
5
+	"github.com/pkg/errors"
6
+	"git.timschuster.info/stephan.graf/SanguControl"
7
+)
8
+
3 9
 func init() {
4
-	cmds["home"] = notyetimplemented
5
-	helpm["home"] = "Calibrates the position of the head"
6
-	cmds["xyz"] = notyetimplemented
7
-	helpm["xyz"] = "Manually moves the head, bypassing the CHC"
8
-	cmds["stop"] = notyetimplemented
9
-	helpm["stop"] = "Issues an emergency stop to all devices and exits"
10
+	cmds["san_home"] = manhome
11
+	helpm["san_home"] = "Calibrates the position of the head"
12
+	cmds["san_xyz"] = manxyz
13
+	helpm["san_xyz"] = "Manually moves the head, bypassing the CHC"
14
+	cmds["san_stop"] = notyetimplemented
15
+	helpm["san_stop"] = "Issues an emergency stop to all devices and exits"
16
+
17
+	cmds["san_con"] = mancon
18
+	helpm["san_con"] = "Starts Sangu Control Console"
19
+
20
+	cmds["getpos"] = getcoords
21
+	helpm["getpos"] = "Prints current position"
22
+
23
+	cmds["step"] = step
24
+	helpm["step"] = "Single step"
25
+}
26
+
27
+func manhome(params []string) error {
28
+	if curCHC == nil {
29
+		fmt.Println("CHC not connected, aborting.")
30
+		return nil
31
+	}
32
+	return curCHC.ThreeDControl.Movehome()
33
+}
34
+
35
+func manxyz(params []string) error {
36
+	if curCHC == nil {
37
+		fmt.Println("CHC not connected, aborting.")
38
+		return nil
39
+	}
40
+	var (
41
+		x, y, z         float64
42
+	)
43
+	x, y, z = -1, -1, -1
44
+
45
+	for k := range params {
46
+	if err := parseParamToFloat64("x", &x, params[k]); err != nil {
47
+	return errors.Wrap(err, "Error while parsing X")
10 48
 }
49
+	if err := parseParamToFloat64("y", &y, params[k]); err != nil {
50
+	return errors.Wrap(err, "Error while parsing Y")
51
+	}
52
+	if err := parseParamToFloat64("z", &z, params[k]); err != nil {
53
+	return errors.Wrap(err, "Error while parsing Z")
54
+	}
55
+	}
56
+
57
+	fmt.Printf("Moving manually to %5.1f %5.1f %5.1f\n", x, y, z)
58
+	return curCHC.ThreeDControl.Moveto(x,y,z)
59
+}
60
+
61
+func mancon(params []string) error {
62
+	if curCHC == nil {
63
+		fmt.Println("CHC not connected, aborting.")
64
+		return nil
65
+	}
66
+	SanguControl.Keyboardcontrol()
67
+	return nil
68
+}
69
+
70
+func getcoords(params []string) error {
71
+	if curCHC == nil {
72
+		fmt.Println("CHC not connected, aborting.")
73
+		return nil
74
+	}
75
+	x,y,z, err := curCHC.ThreeDControl.Getposition(false)
76
+	if err != nil {
77
+		return errors.Wrap(err, "Could not get position")
78
+	}
79
+	fmt.Printf("Current Position: %f, %f, %f\n", x, y, z)
80
+	return nil
81
+}
82
+
83
+func step(params []string) error {
84
+	if curCHC == nil {
85
+		fmt.Println("CHC not connected, aborting.")
86
+		return nil
87
+	}
88
+	var (
89
+		moveX,moveY,moveZ, reverse bool
90
+		stepLength float64
91
+	)
92
+	moveX, moveY, moveZ, reverse = false,false,false,false
93
+	stepLength = 1.0
94
+
95
+	for k := range params {
96
+		if err := parseParamToFloat64("stepl", &stepLength, params[k]); err != nil {
97
+			return errors.Wrap(err, "Error while parsing X")
98
+		}
99
+		if params[k] == "x" {
100
+			moveX = true
101
+		}
102
+		if params[k] == "y" {
103
+			moveY = true
104
+		}
105
+		if params[k] == "z" {
106
+			moveZ = true
107
+		}
108
+		if params[k] == "-" {
109
+			reverse = true
110
+		}
111
+	}
112
+
113
+	return curCHC.ThreeDControl.Singlestep(moveX, moveY, moveZ, stepLength, reverse)
114
+}

+ 7
- 0
exec.go View File

@@ -62,6 +62,13 @@ func help(params []string) error {
62 62
 }
63 63
 
64 64
 func exit(params []string) error {
65
+	if curCHC != nil {
66
+		fmt.Print("Shutting down controller...")
67
+		curCHC.Shutdown()
68
+		fmt.Print("OK!\n")
69
+	} else {
70
+		fmt.Println("Shutting down controller... not connected")
71
+	}
65 72
 	return errExit
66 73
 }
67 74
 

+ 8
- 3
parser.go View File

@@ -67,11 +67,16 @@ func parseParamToInt16(paramName string, paramTar *int16, value string) error {
67 67
 	return nil
68 68
 }
69 69
 
70
-func parseParamToString(paramName string, paramTar *string, value string) error {
70
+func parseParamToInt32(paramName string, paramTar *int32, value string) error {
71 71
 	value = strings.TrimSpace(value)
72 72
 	if strings.HasPrefix(value, paramName+"=") {
73 73
 		value = strings.TrimPrefix(value, paramName+"=")
74
-		*paramTar = value
74
+		fl, err := strconv.ParseInt(value, 10, 32)
75
+		if err != nil {
76
+			return err
77
+		}
78
+		flt := int32(fl)
79
+		*paramTar = flt
75 80
 	}
76 81
 	return nil
77
-}
82
+}

+ 1
- 1
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/Config/HardwareControl.json View File

@@ -12,7 +12,7 @@
12 12
 	"ServoRotateMid":307,
13 13
 	"ThreeDControlPort":"/dev/ttyUSB0",
14 14
 	"ThreeDControlCustomLogger":false,
15
-	"Speed":600,
15
+	"Speed":60,
16 16
 	"SpeedXYOffset":0,
17 17
 	"SpeedZOffset":900,
18 18
 	"RegalAnzahl":3,

+ 4
- 1
vendor/git.timschuster.info/stephan.graf/Complete_hardware_Control/HardwareControl.go View File

@@ -16,6 +16,7 @@ import (
16 16
 	"git.timschuster.info/stephan.graf/Complete_hardware_Control/Config"
17 17
 	"git.timschuster.info/stephan.graf/SanguControl"
18 18
 	"go.rls.moe/misc/adafruitPCA9685"
19
+	"math"
19 20
 )
20 21
 
21 22
 type HardwareControl struct {
@@ -46,6 +47,8 @@ func (h *HardwareControl) waitforarrival() error {
46 47
 			h.Logger.Panicf("Error while waiting for Position %s", err.Error())
47 48
 			h.Shutdown()
48 49
 		}
50
+		x,y,z = math.Trunc(x*10)/10,math.Trunc(y*10)/10,math.Trunc(z*10)/10
51
+		tx,ty,tz = math.Trunc(tx*10)/10,math.Trunc(ty*10)/10,math.Trunc(tz*10)/10
49 52
 		if x-tx == 0 && y-ty == 0 && z-tz == 0 {
50 53
 			break
51 54
 		}
@@ -220,7 +223,7 @@ func NewHardwareControl(logger *log.Logger, path string) *HardwareControl {
220 223
 		return nil
221 224
 	}
222 225
 	//Setup 3D-Controller
223
-	object.ThreeDControl = SanguControl.NewSchrittmotorController(object.config.ThreeDControlPort,
226
+	object.ThreeDControl,_ = SanguControl.NewSchrittmotorController(object.config.ThreeDControlPort,
224 227
 		object.Logger,
225 228
 		object.config.ThreeDControlCustomLogger)
226 229
 	if object.ThreeDControl == nil {

+ 239
- 76
vendor/git.timschuster.info/stephan.graf/SanguControl/sanguinololu_control.go View File

@@ -1,13 +1,14 @@
1 1
 package SanguControl
2 2
 
3 3
 import (
4
-	"errors"
5 4
 	"fmt"
6 5
 	"io"
7 6
 	"os"
8 7
 	"strconv"
9 8
 	"strings"
10 9
 
10
+	"github.com/pkg/errors"
11
+
11 12
 	"bufio"
12 13
 
13 14
 	"log"
@@ -20,6 +21,10 @@ import (
20 21
 	"github.com/jacobsa/go-serial/serial"
21 22
 )
22 23
 
24
+const (
25
+	readTimeout = 10 * time.Second
26
+	readJitter = 1 * time.Millisecond
27
+)
23 28
 type Schrittmotorcontroller struct {
24 29
 	serialstream io.ReadWriteCloser
25 30
 	feedrate     int16
@@ -29,7 +34,7 @@ type Schrittmotorcontroller struct {
29 34
 	locker       *sync.Mutex
30 35
 }
31 36
 
32
-func (s *Schrittmotorcontroller) Moveto(X float64, Y float64, Z float64) {
37
+func (s *Schrittmotorcontroller) Moveto(X float64, Y float64, Z float64) error {
33 38
 	//G1 Xnnn Ynnn Znnn Linear
34 39
 	s.locker.Lock()
35 40
 	var command = "G1 "
@@ -43,22 +48,29 @@ func (s *Schrittmotorcontroller) Moveto(X float64, Y float64, Z float64) {
43 48
 		command = command + "Z" + fmt.Sprintf("%f", Z)
44 49
 	}
45 50
 	command = command + " F" + fmt.Sprintf("%d", s.feedrate) + "\n"
46
-	s.writecommand(command)
51
+	err := s.writecommand(command)
52
+	if err != nil {
53
+		return errors.Wrap(err, "Error at try to write MoveTo")
54
+	}
47 55
 	s.locker.Unlock()
56
+	return nil
48 57
 }
49 58
 
50
-func (s *Schrittmotorcontroller) Movehome() {
59
+func (s *Schrittmotorcontroller) Movehome() error {
51 60
 	//G28
52 61
 	s.locker.Lock()
53 62
 	var command = "G28\n"
54
-	s.writecommand(command)
63
+	err := s.writecommand(command)
64
+	if err != nil {
65
+		return errors.Wrap(err, "Error at try to write MoveHome")
66
+	}
55 67
 	s.locker.Unlock()
68
+	return nil
56 69
 }
57 70
 func (s *Schrittmotorcontroller) parsefloat64(number string) (float64, error) {
58 71
 	val, err := strconv.ParseFloat(strings.TrimSpace(number), 64)
59 72
 	if err != nil {
60
-		s.logger.Fatalf("Error parsing input number: %s\n", err)
61
-		return 0, err
73
+		return 0, errors.Wrap(err, "Error parsing input number")
62 74
 	}
63 75
 	return val, nil
64 76
 }
@@ -84,78 +96,88 @@ func (s *Schrittmotorcontroller) parsecoords(data string, targetcoords bool) (fl
84 96
 					element = strings.TrimPrefix(element, "X:")
85 97
 					xcoord, err = s.parsefloat64(element)
86 98
 					if err != nil {
87
-						s.logger.Fatalf("Error parsing input number: %s\n", err)
88
-						return 0, 0, 0, err
99
+						return 0, 0, 0, errors.Wrap(err, "Could not parse X-target")
89 100
 					}
90 101
 				} else {
91 102
 					xcoord, err = s.parsefloat64(responseparts[index+1])
92 103
 					if err != nil {
93
-						s.logger.Fatalf("Error parsing input number: %s\n", err)
94
-						return 0, 0, 0, err
104
+						return 0, 0, 0, errors.Wrap(err, "Could not parse X")
95 105
 					}
96 106
 				}
97 107
 			} else if strings.HasPrefix(element, "Y:") {
98 108
 				element = strings.TrimPrefix(element, "Y:")
99 109
 				ycoord, err = s.parsefloat64(element)
100 110
 				if err != nil {
101
-					s.logger.Fatalf("Error parsing input number: %s\n", err)
102
-					return 0, 0, 0, err
111
+					return 0, 0, 0, errors.Wrap(err, "Could not parse Y")
103 112
 				}
104 113
 			} else if strings.HasPrefix(element, "Z:") {
105 114
 				element = strings.TrimPrefix(element, "Z:")
106 115
 				zcoord, err = s.parsefloat64(element)
107 116
 				if err != nil {
108
-					s.logger.Fatalf("Error parsing input number: %s\n", err)
109
-					return 0, 0, 0, err
117
+					return 0, 0, 0, errors.Wrap(err, "Could not parse Z")
110 118
 				}
111 119
 			}
112 120
 		}
113 121
 	}
114 122
 	return xcoord, ycoord, zcoord, nil
115 123
 }
116
-func (s *Schrittmotorcontroller) Reset() {
124
+func (s *Schrittmotorcontroller) Reset() error {
117 125
 	s.locker.Lock()
118 126
 	var command = "M999\n"
119
-	s.writecommand(command)
127
+	err := s.writecommand(command)
128
+	if err != nil {
129
+		return errors.Wrap(err, "Error at try to write Reset")
130
+	}
120 131
 	s.locker.Unlock()
132
+	return nil
121 133
 }
122
-func (s *Schrittmotorcontroller) Gettemp() {
134
+func (s *Schrittmotorcontroller) Gettemp() error {
123 135
 	s.locker.Lock()
124 136
 	var command = "M105\n"
125
-	s.writecommand(command)
137
+	err := s.writecommand(command)
138
+	if err != nil {
139
+		return errors.Wrap(err, "Error at try to write Gettemp")
140
+	}
126 141
 	s.locker.Unlock()
142
+	return nil
127 143
 }
128
-func (s *Schrittmotorcontroller) Killit() {
144
+func (s *Schrittmotorcontroller) Killit() error {
129 145
 	s.locker.Lock()
130 146
 	var command = "M112\n"
131
-	s.writecommand(command)
147
+	err := s.writecommand(command)
148
+	if err != nil {
149
+		return errors.Wrap(err, "Error at try to write Killit")
150
+	}
132 151
 	s.locker.Unlock()
152
+	return nil
133 153
 }
134 154
 func (s *Schrittmotorcontroller) Getposition(targetcoords bool) (float64, float64, float64, error) {
135 155
 	//M114
136 156
 	s.locker.Lock()
137 157
 	var command = "M114\n"
138
-	s.writecommand(command)
139
-	starttime := time.Now().Unix()
158
+	err := s.writecommand(command)
159
+	if err != nil {
160
+		return 0, 0, 0, errors.Wrap(err, "Error at try to write Getposition")
161
+	}
162
+	starttime := time.Now()
140 163
 	for {
141 164
 		answer := s.coordbuff.Next()
142 165
 		if answer != nil {
143 166
 			x, y, z, err := s.parsecoords(strings.TrimSpace(answer.(string)), targetcoords)
144 167
 			if err != nil {
145
-				s.logger.Fatalf("Got error by parsing Numbers %s\n", err.Error())
146 168
 				s.locker.Unlock()
147
-				return 0, 0, 0, err
169
+				return 0, 0, 0, errors.Wrap(err, "cannot return Coords error while parsing")
148 170
 
149 171
 			}
150 172
 			s.locker.Unlock()
151 173
 			return x, y, z, nil
152 174
 		}
153
-		if (time.Now().Unix() - starttime) >= 2 {
154
-			s.logger.Fatal("after sending M114 getting no response from reader !!Timeout after 2sec!!")
175
+		if time.Now().Sub(starttime) >= readTimeout {
155 176
 			s.customlogger.Fatal("after sending M114 getting no response from reader !!Timeout after 2sec!!")
156 177
 			s.locker.Unlock()
157 178
 			return 0, 0, 0, errors.New("TIMEOUT at waiting for coord response at getcurrentposition")
158 179
 		}
180
+		time.Sleep(readJitter)
159 181
 	}
160 182
 }
161 183
 
@@ -167,44 +189,57 @@ func (s *Schrittmotorcontroller) Setspeed(speed int16) {
167 189
 
168 190
 //float32 X=0,float32 Y=0,float32 Z=0,int
169 191
 // singlestep exsistiert nur zum manuellen bewegen!!
170
-func (s *Schrittmotorcontroller) Singlestep(X bool, Y bool, Z bool, steplength float64, reverse bool) {
192
+func (s *Schrittmotorcontroller) Singlestep(X bool, Y bool, Z bool, steplength float64, reverse bool) error {
171 193
 	//G91\nG1....\nG90\n
172
-	s.locker.Unlock()
194
+	s.locker.Lock()
173 195
 	var step = steplength
174 196
 	if reverse {
175 197
 		step = -1 * steplength
176 198
 	}
177 199
 	if X {
178
-		s.writecommand(fmt.Sprintf("G91\nG1 X%f\nG90\n", step))
200
+		err := s.writecommand(fmt.Sprintf("G91\nG1 X%f\nG90\n", step))
201
+		if err != nil {
202
+			return errors.Wrap(err, "Error at try to write singlstepX")
203
+		}
179 204
 	} else if Y {
180
-		s.writecommand(fmt.Sprintf("G91\nG1 Y%f\nG90\n", step))
205
+		err := s.writecommand(fmt.Sprintf("G91\nG1 Y%f\nG90\n", step))
206
+		if err != nil {
207
+			return errors.Wrap(err, "Error at try to write singlestepY")
208
+		}
181 209
 	} else if Z {
182
-		s.writecommand(fmt.Sprintf("G91\nG1 Z%f\nG90\n", step))
210
+		err := s.writecommand(fmt.Sprintf("G91\nG1 Z%f\nG90\n", step))
211
+		if err != nil {
212
+			return errors.Wrap(err, "Error at try to write singlestepZ")
213
+		}
183 214
 	}
184 215
 	s.locker.Unlock()
216
+	return nil
185 217
 }
186 218
 
187
-func (s *Schrittmotorcontroller) writecommand(command string) {
219
+func (s *Schrittmotorcontroller) writecommand(command string) error {
188 220
 	//DO NOT TOUCH IT
189 221
 	s.customlogger.Println("sending command " + command)
190 222
 	i, err := s.serialstream.Write([]byte(command))
191 223
 	if err != nil {
192
-		s.logger.Fatalf("Fatal error while writing: %d letters: %s\n", i, err.Error())
224
+		s.customlogger.Fatalf("Fatal error while writing: %d text: %s", i, err.Error())
225
+		return errors.Wrapf(err, "Fatal error while writing: %d", i)
193 226
 	}
227
+	return nil
194 228
 }
195
-func (s *Schrittmotorcontroller) reader() {
229
+func (s *Schrittmotorcontroller) reader() error {
196 230
 	//DO NOT TOUCH IT
197 231
 	s.customlogger.Println("Start reading from serial")
198 232
 	var reader = bufio.NewReader(s.serialstream)
199 233
 	for {
200 234
 		response, err := reader.ReadString('\n')
201 235
 		if err != nil {
202
-			s.logger.Fatal("Error while reding at serial port: " + err.Error())
203
-			return
236
+			s.customlogger.Fatal("Error while reding at serial port: " + err.Error())
237
+			return errors.Wrap(err, "Error while reding at serial port")
204 238
 		}
205 239
 		s.customlogger.Print(response)
206 240
 		//check if command needsto be pushed in responsebuffer
207 241
 		if strings.HasPrefix(response, "X:") {
242
+			s.customlogger.Println("Found coord respone pushing it to fifo")
208 243
 			s.logger.Println("Found coord respone pushing it to fifo")
209 244
 			s.coordbuff.Add(response)
210 245
 		}
@@ -214,7 +249,7 @@ func (s *Schrittmotorcontroller) reader() {
214 249
 // NewSchrittmotorController braucht den pfad zum device in port und das flag logfile legt fest ob er fuer sein Command Logging
215 250
 //den ubergebenen Logger nimmt oder selber einen Anlegt der in das file sanguinololu.log schreibt !!Achtung!! übergebener logger
216 251
 //könnte zu viel overhead im logfile führen
217
-func NewSchrittmotorController(port string, logger *log.Logger, logfile bool) *Schrittmotorcontroller {
252
+func NewSchrittmotorController(port string, logger *log.Logger, logfile bool) (*Schrittmotorcontroller, error) {
218 253
 	var schritt = Schrittmotorcontroller{}
219 254
 	var err error
220 255
 	schritt.locker = &sync.Mutex{}
@@ -226,21 +261,19 @@ func NewSchrittmotorController(port string, logger *log.Logger, logfile bool) *S
226 261
 		MinimumReadSize: 1,
227 262
 	}
228 263
 	if logger == nil {
229
-		return nil
264
+		return nil, errors.New("Logger was nil")
230 265
 	}
231 266
 	schritt.logger = logger
232 267
 	schritt.serialstream, err = serial.Open(options)
233 268
 	schritt.feedrate = 1500
234 269
 	if err != nil {
235
-		schritt.logger.Printf("%s", err)
236
-		return nil
270
+		return nil, errors.Wrap(err, "Error while open serialport")
237 271
 	}
238 272
 	//baue speziellen command logger auf
239 273
 	if logfile {
240 274
 		file, err := os.OpenFile("sanguinololu.log", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0660)
241 275
 		if err != nil {
242
-			schritt.logger.Fatal("3D-PrinterControl reader failed: " + err.Error())
243
-			return nil
276
+			return nil, errors.Wrap(err, "Cannot create or open custom log file")
244 277
 		}
245 278
 		schritt.customlogger = log.New(file, "sanguinololu: ", log.LUTC)
246 279
 	} else {
@@ -250,83 +283,209 @@ func NewSchrittmotorController(port string, logger *log.Logger, logfile bool) *S
250 283
 	schritt.coordbuff = fifo.NewQueue()
251 284
 	//starte den reader am seriellenport
252 285
 	go schritt.reader()
253
-	return &schritt
286
+	return &schritt, nil
254 287
 }
255 288
 
256 289
 // Keyboardcontrol mit vorsicht zu genießen startet eine komplett neue Controller
257 290
 //instanz mit consolen eingabe und logging auf die console
258 291
 func Keyboardcontrol() {
259 292
 	logger := log.New(os.Stderr, "sanguinololu", log.LUTC|log.Llongfile)
260
-	schritt := NewSchrittmotorController("/dev/ttyUSB0", logger, false)
293
+	schritt, err := NewSchrittmotorController("/dev/ttyUSB0", logger, false)
294
+	if err != nil {
295
+		fmt.Printf("Error while init SchrittControl: %s\n", err.Error())
296
+	}
261 297
 	bufin := bufio.NewReader(os.Stdin)
262 298
 	for {
263 299
 		fmt.Print("CMD> ")
264 300
 		command, err := bufin.ReadString('\n')
265 301
 		if err != nil {
302
+			fmt.Printf("Error while Reading command from console: %s\n", err.Error())
266 303
 			return
267 304
 		}
268 305
 		command = strings.TrimSpace(command)
269 306
 		switch command {
270 307
 		case "G28":
271
-			schritt.Movehome()
308
+			err = schritt.Movehome()
309
+			if err != nil {
310
+				fmt.Printf("%s\n", err)
311
+				return
312
+			}
272 313
 		case "M114":
273
-			fmt.Println(schritt.Getposition(false))
314
+			x, y, z, err := schritt.Getposition(false)
315
+			if err != nil {
316
+				fmt.Printf("%s\n", err)
317
+				return
318
+			}
319
+			fmt.Printf("X: %f, Y: %f, Z: %f\n", x, y, z)
274 320
 		case "M114 target":
275
-			fmt.Println(schritt.Getposition(true))
321
+			x, y, z, err := schritt.Getposition(true)
322
+			if err != nil {
323
+				fmt.Printf("%s\n", err)
324
+				return
325
+			}
326
+			fmt.Printf("X: %f, Y: %f, Z: %f\n", x, y, z)
276 327
 		case "x":
277
-			schritt.Singlestep(true, false, false, 1.0, false)
328
+			err = schritt.Singlestep(true, false, false, 1.0, false)
329
+			if err != nil {
330
+				fmt.Printf("%s\n", err)
331
+				return
332
+			}
278 333
 		case "y":
279
-			schritt.Singlestep(false, true, false, 1.0, false)
334
+			err = schritt.Singlestep(false, true, false, 1.0, false)
335
+			if err != nil {
336
+				fmt.Printf("%s\n", err)
337
+				return
338
+			}
280 339
 		case "z":
281
-			schritt.Singlestep(false, false, true, 1.0, false)
340
+			err = schritt.Singlestep(false, false, true, 1.0, false)
341
+			if err != nil {
342
+				fmt.Printf("%s\n", err)
343
+				return
344
+			}
282 345
 		case "-x":
283
-			schritt.Singlestep(true, false, false, 1.0, true)
346
+			err = schritt.Singlestep(true, false, false, 1.0, true)
347
+			if err != nil {
348
+				fmt.Printf("%s\n", err)
349
+				return
350
+			}
284 351
 		case "-y":
285
-			schritt.Singlestep(false, true, false, 1.0, true)
352
+			err = schritt.Singlestep(false, true, false, 1.0, true)
353
+			if err != nil {
354
+				fmt.Printf("%s\n", err)
355
+				return
356
+			}
286 357
 		case "-z":
287
-			schritt.Singlestep(false, false, true, 1.0, true)
358
+			err = schritt.Singlestep(false, false, true, 1.0, true)
359
+			if err != nil {
360
+				fmt.Printf("%s\n", err)
361
+				return
362
+			}
288 363
 		case "x2":
289
-			schritt.Singlestep(true, false, false, 0.5, false)
364
+			err = schritt.Singlestep(true, false, false, 0.5, false)
365
+			if err != nil {
366
+				fmt.Printf("%s\n", err)
367
+				return
368
+			}
290 369
 		case "y2":
291
-			schritt.Singlestep(false, true, false, 0.5, false)
370
+			err = schritt.Singlestep(false, true, false, 0.5, false)
371
+			if err != nil {
372
+				fmt.Printf("%s\n", err)
373
+				return
374
+			}
292 375
 		case "z2":
293
-			schritt.Singlestep(false, false, true, 0.5, false)
376
+			err = schritt.Singlestep(false, false, true, 0.5, false)
377
+			if err != nil {
378
+				fmt.Printf("%s\n", err)
379
+				return
380
+			}
294 381
 		case "-x2":
295
-			schritt.Singlestep(true, false, false, 0.5, true)
382
+			err = schritt.Singlestep(true, false, false, 0.5, true)
383
+			if err != nil {
384
+				fmt.Printf("%s\n", err)
385
+				return
386
+			}
296 387
 		case "-y2":
297
-			schritt.Singlestep(false, true, false, 0.5, true)
388
+			err = schritt.Singlestep(false, true, false, 0.5, true)
389
+			if err != nil {
390
+				fmt.Printf("%s\n", err)
391
+				return
392
+			}
298 393
 		case "-z2":
299
-			schritt.Singlestep(false, false, true, 0.5, true)
394
+			err = schritt.Singlestep(false, false, true, 0.5, true)
395
+			if err != nil {
396
+				fmt.Printf("%s\n", err)
397
+				return
398
+			}
300 399
 		case "x25":
301
-			schritt.Singlestep(true, false, false, 0.25, false)
400
+			err = schritt.Singlestep(true, false, false, 0.25, false)
401
+			if err != nil {
402
+				fmt.Printf("%s\n", err)
403
+				return
404
+			}
302 405
 		case "y25":
303
-			schritt.Singlestep(false, true, false, 0.25, false)
406
+			err = schritt.Singlestep(false, true, false, 0.25, false)
407
+			if err != nil {
408
+				fmt.Printf("%s\n", err)
409
+				return
410
+			}
304 411
 		case "z25":
305
-			schritt.Singlestep(false, false, true, 0.25, false)
412
+			err = schritt.Singlestep(false, false, true, 0.25, false)
413
+			if err != nil {
414
+				fmt.Printf("%s\n", err)
415
+				return
416
+			}
306 417
 		case "-x25":
307
-			schritt.Singlestep(true, false, false, 0.25, true)
418
+			err = schritt.Singlestep(true, false, false, 0.25, true)
419
+			if err != nil {
420
+				fmt.Printf("%s\n", err)
421
+				return
422
+			}
308 423
 		case "-y25":
309
-			schritt.Singlestep(false, true, false, 0.25, true)
424
+			err = schritt.Singlestep(false, true, false, 0.25, true)
425
+			if err != nil {
426
+				fmt.Printf("%s\n", err)
427
+				return
428
+			}
310 429
 		case "-z25":
311
-			schritt.Singlestep(false, false, true, 0.25, true)
430
+			err = schritt.Singlestep(false, false, true, 0.25, true)
431
+			if err != nil {
432
+				fmt.Printf("%s\n", err)
433
+				return
434
+			}
312 435
 		case "x8":
313
-			schritt.Singlestep(true, false, false, 0.125, false)
436
+			err = schritt.Singlestep(true, false, false, 0.125, false)
437
+			if err != nil {
438
+				fmt.Printf("%s\n", err)
439
+				return
440
+			}
314 441
 		case "y8":
315
-			schritt.Singlestep(false, true, false, 0.125, false)
442
+			err = schritt.Singlestep(false, true, false, 0.125, false)
443
+			if err != nil {
444
+				fmt.Printf("%s\n", err)
445
+				return
446
+			}
316 447
 		case "z8":
317
-			schritt.Singlestep(false, false, true, 0.125, false)
448
+			err = schritt.Singlestep(false, false, true, 0.125, false)
449
+			if err != nil {
450
+				fmt.Printf("%s\n", err)
451
+				return
452
+			}
318 453
 		case "-x8":
319
-			schritt.Singlestep(true, false, false, 0.125, true)
454
+			err = schritt.Singlestep(true, false, false, 0.125, true)
455
+			if err != nil {
456
+				fmt.Printf("%s\n", err)
457
+				return
458
+			}
320 459
 		case "-y8":
321
-			schritt.Singlestep(false, true, false, 0.125, true)
460
+			err = schritt.Singlestep(false, true, false, 0.125, true)
461
+			if err != nil {
462
+				fmt.Printf("%s\n", err)
463
+				return
464
+			}
322 465
 		case "-z8":
323
-			schritt.Singlestep(false, false, true, 0.125, true)
466
+			err = schritt.Singlestep(false, false, true, 0.125, true)
467
+			if err != nil {
468
+				fmt.Printf("%s\n", err)
469
+				return
470
+			}
324 471
 		case "M999":
325
-			schritt.Reset()
472
+			err = schritt.Reset()
473
+			if err != nil {
474
+				fmt.Printf("%s\n", err)
475
+				return
476
+			}
326 477
 		case "M105":
327
-			schritt.Gettemp()
478
+			err = schritt.Gettemp()
479
+			if err != nil {
480
+				fmt.Printf("%s\n", err)
481
+				return
482
+			}
328 483
 		case "M112":
329
-			schritt.Killit()
484
+			err = schritt.Killit()
485
+			if err != nil {
486
+				fmt.Printf("%s\n", err)
487
+				return
488
+			}
330 489
 		default:
331 490
 			if strings.HasPrefix(command, "G1 ") {
332 491
 				command = strings.TrimPrefix(command, "G1 ")
@@ -365,7 +524,11 @@ func Keyboardcontrol() {
365 524
 					zcoord = val
366 525
 
367 526
 				}
368
-				schritt.Moveto(xcoord, ycoord, zcoord)
527
+				err = schritt.Moveto(xcoord, ycoord, zcoord)
528
+				if err != nil {
529
+					fmt.Printf("%s\n", err)
530
+					return
531
+				}
369 532
 			} else if strings.HasPrefix(command, "speed ") {
370 533
 				command = strings.TrimPrefix(command, "speed ")
371 534
 				val, err := strconv.Atoi(strings.TrimSpace(command))

+ 23
- 0
vendor/github.com/pkg/errors/LICENSE View File

@@ -0,0 +1,23 @@
1
+Copyright (c) 2015, Dave Cheney <dave@cheney.net>
2
+All rights reserved.
3
+
4
+Redistribution and use in source and binary forms, with or without
5
+modification, are permitted provided that the following conditions are met:
6
+
7
+* Redistributions of source code must retain the above copyright notice, this
8
+  list of conditions and the following disclaimer.
9
+
10
+* Redistributions in binary form must reproduce the above copyright notice,
11
+  this list of conditions and the following disclaimer in the documentation
12
+  and/or other materials provided with the distribution.
13
+
14
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 52
- 0
vendor/github.com/pkg/errors/README.md View File

@@ -0,0 +1,52 @@
1
+# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors)
2
+
3
+Package errors provides simple error handling primitives.
4
+
5
+`go get github.com/pkg/errors`
6
+
7
+The traditional error handling idiom in Go is roughly akin to
8
+```go
9
+if err != nil {
10
+        return err
11
+}
12
+```
13
+which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error.
14
+
15
+## Adding context to an error
16
+
17
+The errors.Wrap function returns a new error that adds context to the original error. For example
18
+```go
19
+_, err := ioutil.ReadAll(r)
20
+if err != nil {
21
+        return errors.Wrap(err, "read failed")
22
+}
23
+```
24
+## Retrieving the cause of an error
25
+
26
+Using `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`.
27
+```go
28
+type causer interface {
29
+        Cause() error
30
+}
31
+```
32
+`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example:
33
+```go
34
+switch err := errors.Cause(err).(type) {
35
+case *MyError:
36
+        // handle specifically
37
+default:
38
+        // unknown error
39
+}
40
+```
41
+
42
+[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors).
43
+
44
+## Contributing
45
+
46
+We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high.
47
+
48
+Before proposing a change, please discuss your change by raising an issue.
49
+
50
+## Licence
51
+
52
+BSD-2-Clause

+ 32
- 0
vendor/github.com/pkg/errors/appveyor.yml View File

@@ -0,0 +1,32 @@
1
+version: build-{build}.{branch}
2
+
3
+clone_folder: C:\gopath\src\github.com\pkg\errors
4
+shallow_clone: true # for startup speed
5
+
6
+environment:
7
+  GOPATH: C:\gopath
8
+
9
+platform:
10
+  - x64
11
+
12
+# http://www.appveyor.com/docs/installed-software
13
+install:
14
+  # some helpful output for debugging builds
15
+  - go version
16
+  - go env
17
+  # pre-installed MinGW at C:\MinGW is 32bit only
18
+  # but MSYS2 at C:\msys64 has mingw64
19
+  - set PATH=C:\msys64\mingw64\bin;%PATH%
20
+  - gcc --version
21
+  - g++ --version
22
+
23
+build_script:
24
+  - go install -v ./...
25
+
26
+test_script:
27
+  - set PATH=C:\gopath\bin;%PATH%
28
+  - go test -v ./...
29
+
30
+#artifacts:
31
+#  - path: '%GOPATH%\bin\*.exe'
32
+deploy: off

+ 269
- 0
vendor/github.com/pkg/errors/errors.go View File

@@ -0,0 +1,269 @@
1
+// Package errors provides simple error handling primitives.
2
+//
3
+// The traditional error handling idiom in Go is roughly akin to
4
+//
5
+//     if err != nil {
6
+//             return err
7
+//     }
8
+//
9
+// which applied recursively up the call stack results in error reports
10
+// without context or debugging information. The errors package allows
11
+// programmers to add context to the failure path in their code in a way
12
+// that does not destroy the original value of the error.
13
+//
14
+// Adding context to an error
15
+//
16
+// The errors.Wrap function returns a new error that adds context to the
17
+// original error by recording a stack trace at the point Wrap is called,
18
+// and the supplied message. For example
19
+//
20
+//     _, err := ioutil.ReadAll(r)
21
+//     if err != nil {
22
+//             return errors.Wrap(err, "read failed")
23
+//     }
24
+//
25
+// If additional control is required the errors.WithStack and errors.WithMessage
26
+// functions destructure errors.Wrap into its component operations of annotating
27
+// an error with a stack trace and an a message, respectively.
28
+//
29
+// Retrieving the cause of an error
30
+//
31
+// Using errors.Wrap constructs a stack of errors, adding context to the
32
+// preceding error. Depending on the nature of the error it may be necessary
33
+// to reverse the operation of errors.Wrap to retrieve the original error
34
+// for inspection. Any error value which implements this interface
35
+//
36
+//     type causer interface {
37
+//             Cause() error
38
+//     }
39
+//
40
+// can be inspected by errors.Cause. errors.Cause will recursively retrieve
41
+// the topmost error which does not implement causer, which is assumed to be
42
+// the original cause. For example:
43
+//
44
+//     switch err := errors.Cause(err).(type) {
45
+//     case *MyError:
46
+//             // handle specifically
47
+//     default:
48
+//             // unknown error
49
+//     }
50
+//
51
+// causer interface is not exported by this package, but is considered a part
52
+// of stable public API.
53
+//
54
+// Formatted printing of errors
55
+//
56
+// All error values returned from this package implement fmt.Formatter and can
57
+// be formatted by the fmt package. The following verbs are supported
58
+//
59
+//     %s    print the error. If the error has a Cause it will be
60
+//           printed recursively
61
+//     %v    see %s
62
+//     %+v   extended format. Each Frame of the error's StackTrace will
63
+//           be printed in detail.
64
+//
65
+// Retrieving the stack trace of an error or wrapper
66
+//
67
+// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
68
+// invoked. This information can be retrieved with the following interface.
69
+//
70
+//     type stackTracer interface {
71
+//             StackTrace() errors.StackTrace
72
+//     }
73
+//
74
+// Where errors.StackTrace is defined as
75
+//
76
+//     type StackTrace []Frame
77
+//
78
+// The Frame type represents a call site in the stack trace. Frame supports
79
+// the fmt.Formatter interface that can be used for printing information about
80
+// the stack trace of this error. For example:
81
+//
82
+//     if err, ok := err.(stackTracer); ok {
83
+//             for _, f := range err.StackTrace() {
84
+//                     fmt.Printf("%+s:%d", f)
85
+//             }
86
+//     }
87
+//
88
+// stackTracer interface is not exported by this package, but is considered a part
89
+// of stable public API.
90
+//
91
+// See the documentation for Frame.Format for more details.
92
+package errors
93
+
94
+import (
95
+	"fmt"
96
+	"io"
97
+)
98
+
99
+// New returns an error with the supplied message.
100
+// New also records the stack trace at the point it was called.
101
+func New(message string) error {
102
+	return &fundamental{
103
+		msg:   message,
104
+		stack: callers(),
105
+	}
106
+}
107
+
108
+// Errorf formats according to a format specifier and returns the string
109
+// as a value that satisfies error.
110
+// Errorf also records the stack trace at the point it was called.
111
+func Errorf(format string, args ...interface{}) error {
112
+	return &fundamental{
113
+		msg:   fmt.Sprintf(format, args...),
114
+		stack: callers(),
115
+	}
116
+}
117
+
118
+// fundamental is an error that has a message and a stack, but no caller.
119
+type fundamental struct {
120
+	msg string
121
+	*stack
122
+}
123
+
124
+func (f *fundamental) Error() string { return f.msg }
125
+
126
+func (f *fundamental) Format(s fmt.State, verb rune) {
127
+	switch verb {
128
+	case 'v':
129
+		if s.Flag('+') {
130
+			io.WriteString(s, f.msg)
131
+			f.stack.Format(s, verb)
132
+			return
133
+		}
134
+		fallthrough
135
+	case 's':
136
+		io.WriteString(s, f.msg)
137
+	case 'q':
138
+		fmt.Fprintf(s, "%q", f.msg)
139
+	}
140
+}
141
+
142
+// WithStack annotates err with a stack trace at the point WithStack was called.
143
+// If err is nil, WithStack returns nil.
144
+func WithStack(err error) error {
145
+	if err == nil {
146
+		return nil
147
+	}
148
+	return &withStack{
149
+		err,
150
+		callers(),
151
+	}
152
+}
153
+
154
+type withStack struct {
155
+	error
156
+	*stack
157
+}
158
+
159
+func (w *withStack) Cause() error { return w.error }
160
+
161
+func (w *withStack) Format(s fmt.State, verb rune) {
162
+	switch verb {
163
+	case 'v':
164
+		if s.Flag('+') {
165
+			fmt.Fprintf(s, "%+v", w.Cause())
166
+			w.stack.Format(s, verb)
167
+			return
168
+		}
169
+		fallthrough
170
+	case 's':
171
+		io.WriteString(s, w.Error())
172
+	case 'q':
173
+		fmt.Fprintf(s, "%q", w.Error())
174
+	}
175
+}
176
+
177
+// Wrap returns an error annotating err with a stack trace
178
+// at the point Wrap is called, and the supplied message.
179
+// If err is nil, Wrap returns nil.
180
+func Wrap(err error, message string) error {
181
+	if err == nil {
182
+		return nil
183
+	}
184
+	err = &withMessage{
185
+		cause: err,
186
+		msg:   message,
187
+	}
188
+	return &withStack{
189
+		err,
190
+		callers(),
191
+	}
192
+}
193
+
194
+// Wrapf returns an error annotating err with a stack trace
195
+// at the point Wrapf is call, and the format specifier.
196
+// If err is nil, Wrapf returns nil.
197
+func Wrapf(err error, format string, args ...interface{}) error {
198
+	if err == nil {
199
+		return nil
200
+	}
201
+	err = &withMessage{
202
+		cause: err,
203
+		msg:   fmt.Sprintf(format, args...),
204
+	}
205
+	return &withStack{
206
+		err,
207
+		callers(),
208
+	}
209
+}
210
+
211
+// WithMessage annotates err with a new message.
212
+// If err is nil, WithMessage returns nil.
213
+func WithMessage(err error, message string) error {
214
+	if err == nil {
215
+		return nil
216
+	}
217
+	return &withMessage{
218
+		cause: err,
219
+		msg:   message,
220
+	}
221
+}
222
+
223
+type withMessage struct {
224
+	cause error
225
+	msg   string
226
+}
227
+
228
+func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() }
229
+func (w *withMessage) Cause() error  { return w.cause }
230
+
231
+func (w *withMessage) Format(s fmt.State, verb rune) {
232
+	switch verb {
233
+	case 'v':
234
+		if s.Flag('+') {
235
+			fmt.Fprintf(s, "%+v\n", w.Cause())
236
+			io.WriteString(s, w.msg)
237
+			return
238
+		}
239
+		fallthrough
240
+	case 's', 'q':
241
+		io.WriteString(s, w.Error())
242
+	}
243
+}
244
+
245
+// Cause returns the underlying cause of the error, if possible.
246
+// An error value has a cause if it implements the following
247
+// interface:
248
+//
249
+//     type causer interface {
250
+//            Cause() error
251
+//     }
252
+//
253
+// If the error does not implement Cause, the original error will
254
+// be returned. If the error is nil, nil will be returned without further
255
+// investigation.
256
+func Cause(err error) error {
257
+	type causer interface {
258
+		Cause() error
259
+	}
260
+
261
+	for err != nil {
262
+		cause, ok := err.(causer)
263
+		if !ok {
264
+			break
265
+		}
266
+		err = cause.Cause()
267
+	}
268
+	return err
269
+}

+ 186
- 0
vendor/github.com/pkg/errors/stack.go View File

@@ -0,0 +1,186 @@
1
+package errors
2
+
3
+import (
4
+	"fmt"
5
+	"io"
6
+	"path"
7
+	"runtime"
8
+	"strings"
9
+)
10
+
11
+// Frame represents a program counter inside a stack frame.
12
+type Frame uintptr
13
+
14
+// pc returns the program counter for this frame;
15
+// multiple frames may have the same PC value.
16
+func (f Frame) pc() uintptr { return uintptr(f) - 1 }
17
+
18
+// file returns the full path to the file that contains the
19
+// function for this Frame's pc.
20
+func (f Frame) file() string {
21
+	fn := runtime.FuncForPC(f.pc())
22
+	if fn == nil {
23
+		return "unknown"
24
+	}
25
+	file, _ := fn.FileLine(f.pc())
26
+	return file
27
+}
28
+
29
+// line returns the line number of source code of the
30
+// function for this Frame's pc.
31
+func (f Frame) line() int {
32
+	fn := runtime.FuncForPC(f.pc())
33
+	if fn == nil {
34
+		return 0
35
+	}
36
+	_, line := fn.FileLine(f.pc())
37
+	return line
38
+}
39
+
40
+// Format formats the frame according to the fmt.Formatter interface.
41
+//
42
+//    %s    source file
43
+//    %d    source line
44
+//    %n    function name
45
+//    %v    equivalent to %s:%d
46
+//
47
+// Format accepts flags that alter the printing of some verbs, as follows:
48
+//
49
+//    %+s   path of source file relative to the compile time GOPATH
50
+//    %+v   equivalent to %+s:%d
51
+func (f Frame) Format(s fmt.State, verb rune) {
52
+	switch verb {
53
+	case 's':
54
+		switch {
55
+		case s.Flag('+'):
56
+			pc := f.pc()
57
+			fn := runtime.FuncForPC(pc)
58
+			if fn == nil {
59
+				io.WriteString(s, "unknown")
60
+			} else {
61
+				file, _ := fn.FileLine(pc)
62
+				fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
63
+			}
64
+		default:
65
+			io.WriteString(s, path.Base(f.file()))
66
+		}
67
+	case 'd':
68
+		fmt.Fprintf(s, "%d", f.line())
69
+	case 'n':
70
+		name := runtime.FuncForPC(f.pc()).Name()
71
+		io.WriteString(s, funcname(name))
72
+	case 'v':
73
+		f.Format(s, 's')
74
+		io.WriteString(s, ":")
75
+		f.Format(s, 'd')
76
+	}
77
+}
78
+
79
+// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
80
+type StackTrace []Frame
81
+
82
+// Format formats the stack of Frames according to the fmt.Formatter interface.
83
+//
84
+//    %s	lists source files for each Frame in the stack
85
+//    %v	lists the source file and line number for each Frame in the stack
86
+//
87
+// Format accepts flags that alter the printing of some verbs, as follows:
88
+//
89
+//    %+v   Prints filename, function, and line number for each Frame in the stack.
90
+func (st StackTrace) Format(s fmt.State, verb rune) {
91
+	switch verb {
92
+	case 'v':
93
+		switch {
94
+		case s.Flag('+'):
95
+			for _, f := range st {
96
+				fmt.Fprintf(s, "\n%+v", f)
97
+			}
98
+		case s.Flag('#'):
99
+			fmt.Fprintf(s, "%#v", []Frame(st))
100
+		default:
101
+			fmt.Fprintf(s, "%v", []Frame(st))
102
+		}
103
+	case 's':
104
+		fmt.Fprintf(s, "%s", []Frame(st))
105
+	}
106
+}
107
+
108
+// stack represents a stack of program counters.
109
+type stack []uintptr
110
+
111
+func (s *stack) Format(st fmt.State, verb rune) {
112
+	switch verb {
113
+	case 'v':
114
+		switch {
115
+		case st.Flag('+'):
116
+			for _, pc := range *s {
117
+				f := Frame(pc)
118
+				fmt.Fprintf(st, "\n%+v", f)
119
+			}
120
+		}
121
+	}
122
+}
123
+
124
+func (s *stack) StackTrace() StackTrace {
125
+	f := make([]Frame, len(*s))
126
+	for i := 0; i < len(f); i++ {
127
+		f[i] = Frame((*s)[i])
128
+	}
129
+	return f
130
+}
131
+
132
+func callers() *stack {
133
+	const depth = 32
134
+	var pcs [depth]uintptr
135
+	n := runtime.Callers(3, pcs[:])
136
+	var st stack = pcs[0:n]
137
+	return &st
138
+}
139
+
140
+// funcname removes the path prefix component of a function's name reported by func.Name().
141
+func funcname(name string) string {
142
+	i := strings.LastIndex(name, "/")
143
+	name = name[i+1:]
144
+	i = strings.Index(name, ".")
145
+	return name[i+1:]
146
+}
147
+
148
+func trimGOPATH(name, file string) string {
149
+	// Here we want to get the source file path relative to the compile time
150
+	// GOPATH. As of Go 1.6.x there is no direct way to know the compiled
151
+	// GOPATH at runtime, but we can infer the number of path segments in the
152
+	// GOPATH. We note that fn.Name() returns the function name qualified by
153
+	// the import path, which does not include the GOPATH. Thus we can trim
154
+	// segments from the beginning of the file path until the number of path
155
+	// separators remaining is one more than the number of path separators in
156
+	// the function name. For example, given:
157
+	//
158
+	//    GOPATH     /home/user
159
+	//    file       /home/user/src/pkg/sub/file.go
160
+	//    fn.Name()  pkg/sub.Type.Method
161
+	//
162
+	// We want to produce:
163
+	//
164
+	//    pkg/sub/file.go
165
+	//
166
+	// From this we can easily see that fn.Name() has one less path separator
167
+	// than our desired output. We count separators from the end of the file
168
+	// path until it finds two more than in the function name and then move
169
+	// one character forward to preserve the initial path segment without a
170
+	// leading separator.
171
+	const sep = "/"
172
+	goal := strings.Count(name, sep) + 2
173
+	i := len(file)
174
+	for n := 0; n < goal; n++ {
175
+		i = strings.LastIndex(file[:i], sep)
176
+		if i == -1 {
177
+			// not enough separators found, set i so that the slice expression
178
+			// below leaves file unmodified
179
+			i = -len(sep)
180
+			break
181
+		}
182
+	}
183
+	// get back to 0 or trim the leading separator
184
+	file = file[i+len(sep):]
185
+	return file
186
+}

+ 9
- 3
vendor/vendor.json View File

@@ -15,10 +15,10 @@
15 15
 			"revisionTime": "2017-05-16T08:31:18Z"
16 16
 		},
17 17
 		{
18
-			"checksumSHA1": "mbYDznOZdVjRq3YNqHvHqkfDHnA=",
18
+			"checksumSHA1": "L+6dSYM0B5CruK/PAoEjm7ASmFI=",
19 19
 			"path": "git.timschuster.info/stephan.graf/SanguControl",
20
-			"revision": "d977a245bdf8ea6d009919cf5a06e5d7cc14acd5",
21
-			"revisionTime": "2017-05-12T17:24:30Z"
20
+			"revision": "ba35dc96dc293d8746b41a2dd454a406a0e53477",
21
+			"revisionTime": "2017-05-16T11:04:59Z"
22 22
 		},
23 23
 		{
24 24
 			"checksumSHA1": "aTYPm16eYDQhbVLgreCGwvV2klw=",
@@ -44,6 +44,12 @@
44 44
 			"revision": "6f298b3ae27eacbbad51a827dcce21d792fb45e1",
45 45
 			"revisionTime": "2016-04-01T03:02:10Z"
46 46
 		},
47
+		{
48
+			"checksumSHA1": "rJab1YdNhQooDiBWNnt7TLWPyBU=",
49
+			"path": "github.com/pkg/errors",
50
+			"revision": "c605e284fe17294bda444b34710735b29d1a9d90",
51
+			"revisionTime": "2017-05-05T04:36:39Z"
52
+		},
47 53
 		{
48 54
 			"checksumSHA1": "LuFv4/jlrmFNnDb/5SCSEPAM9vU=",
49 55
 			"path": "github.com/pmezard/go-difflib/difflib",

Loading…
Cancel
Save