Refactor kafka to pure Go (franz-go), fix DBC stubs, update Dockerfile
This commit is contained in:
168
pkg/can-go/README.md
Normal file
168
pkg/can-go/README.md
Normal file
@@ -0,0 +1,168 @@
|
||||
# :electric_plug: CAN Go
|
||||
|
||||
[![PkgGoDev][pkg-badge]][pkg]
|
||||
[![GoReportCard][report-badge]][report]
|
||||
[![Codecov][codecov-badge]][codecov]
|
||||
|
||||
[pkg-badge]: https://pkg.go.dev/badge/github.com/Fisker-Inc/project-ai-can-go
|
||||
[pkg]: https://pkg.go.dev/github.com/Fisker-Inc/project-ai-can-go
|
||||
[report-badge]: https://goreportcard.com/badge/github.com/Fisker-Inc/project-ai-can-go
|
||||
[report]: https://goreportcard.com/report/github.com/Fisker-Inc/project-ai-can-go
|
||||
[codecov-badge]: https://codecov.io/gh/einride/can-go/branch/master/graph/badge.svg
|
||||
[codecov]: https://codecov.io/gh/einride/can-go
|
||||
|
||||
CAN toolkit for Go programmers.
|
||||
|
||||
can-go makes use of the Linux SocketCAN abstraction for CAN communication.
|
||||
(See the [SocketCAN][socketcan] documentation for more details).
|
||||
|
||||
[socketcan]: https://www.kernel.org/doc/Documentation/networking/can.txt
|
||||
|
||||
## Modifications to the Original Repo
|
||||
Original repo: `https://github.com/jshiv/can-go/tree/623b1140d54a845026249a5bbbaf23f44c614173`.
|
||||
|
||||
Comment out the value descriptor generation code within `can-go/internal/generate/file.go`, lines 128-141. This code creates compile errors due to duplicate values within the `.dbc` file provided.
|
||||
|
||||
## DBC Go Code Library Generation
|
||||
1. Place `.dbc` file into `orig/` folder.
|
||||
2. Run `scripts/main.go`:
|
||||
```
|
||||
go run scripts/main.go
|
||||
```
|
||||
This will translate all Chinese variable values within the file to English. Any non-alphanumeric characters are also removed. **NOTE** The default read file is labelled `orig/121-N60AB_ADASBUS_Matrix_CANFD_V2.3.dbc` and the default write file is labelled `dbc/n60.dbc`.
|
||||
|
||||
3. There will still be leftover Chinese characters in the `.dbc` file, I chose to just remove them.
|
||||
4. Generate Go code from cleaned `.dbc` file:
|
||||
```
|
||||
can-go> go run cmd/cantool/main.go generate data/dbc dbc
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Decoding CAN messages
|
||||
|
||||
Decoding CAN messages from byte arrays can be done using `can.Payload`
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// DBC file
|
||||
var dbcFile = []byte(`
|
||||
VERSION ""
|
||||
NS_ :
|
||||
BS_:
|
||||
BU_: DBG DRIVER IO MOTOR SENSOR
|
||||
|
||||
BO_ 1530 DisconnectState: 14 MOTOR
|
||||
SG_ LockCountRearRight : 91|20@0+ (1,0) [0|1048575] "" IO
|
||||
SG_ DisconnectStateRearRight : 95|4@0+ (1,0) [0|5] "" IO
|
||||
SG_ CurrentRearRight : 79|16@0+ (1,0) [0|65535] "" IO
|
||||
SG_ DisconnectStateRearRightTarget : 64|1@0+ (1,0) [0|1] "" IO
|
||||
SG_ TargetSpeedRearRight : 63|15@0+ (0.125,-2048) [-2048|2047.875] "rad/s" IO
|
||||
SG_ LockCountRearLeft : 35|20@0+ (1,0) [0|1048575] "" IO
|
||||
SG_ DisconnectStateRearLeft : 39|4@0+ (1,0) [0|5] "" IO
|
||||
SG_ CurrentRearLeft : 23|16@0+ (1,0) [0|65535] "" IO
|
||||
SG_ DisconnectStateRearLeftTarget : 8|1@0+ (1,0) [0|1] "" IO
|
||||
SG_ TargetSpeedRearLeft : 7|15@0+ (0.125,-2048) [-2048|2047.875] "rad/s" IO
|
||||
|
||||
VAL_ 1530 DisconnectStateRearRight 0 "Undefined" 1 "Locked" 2 "Unlocked" 3 "Locking" 4 "Unlocking" 5 "Faulted" ;
|
||||
VAL_ 1530 DisconnectStateRearLeft 0 "Undefined" 1 "Locked" 2 "Unlocked" 3 "Locking" 4 "Unlocking" 5 "Faulted" ;
|
||||
`)
|
||||
|
||||
// Create payload from hex string
|
||||
byteStringHex := "8000000420061880000005200600"
|
||||
p, _ := can.PayloadFromHex(byteStringHex)
|
||||
|
||||
// Load example dbc file
|
||||
c, _ := generate.Compile("test.dbc", dbcFile)
|
||||
db := *c.Database
|
||||
|
||||
// Decode message frame ID 1530
|
||||
message, _ := db.Message(uint32(1530))
|
||||
decodedSignals := message.Decode(&p)
|
||||
for _, signal := range decodedSignals {
|
||||
fmt.Printf("Signal: %s, Value: %f, Description: %s\n", signal.Signal.Name, signal.Value, signal.Description)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
Signal: TargetSpeedRearLeft, Value: 0.000000, Description:
|
||||
Signal: DisconnectStateRearLeftTarget, Value: 0.000000, Description:
|
||||
Signal: CurrentRearLeft, Value: 4.000000, Description:
|
||||
Signal: LockCountRearLeft, Value: 1560.000000, Description:
|
||||
Signal: DisconnectStateRearLeft, Value: 2.000000, Description: Unlocked
|
||||
Signal: TargetSpeedRearRight, Value: 0.000000, Description:
|
||||
Signal: DisconnectStateRearRightTarget, Value: 0.000000, Description:
|
||||
Signal: CurrentRearRight, Value: 5.000000, Description:
|
||||
Signal: LockCountRearRight, Value: 1536.000000, Description:
|
||||
Signal: DisconnectStateRearRight, Value: 2.000000, Description: Unlocked
|
||||
```
|
||||
|
||||
|
||||
### Receiving CAN frames
|
||||
|
||||
Receiving CAN frames from a socketcan interface.
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// Error handling omitted to keep example simple
|
||||
conn, _ := socketcan.DialContext(context.Background(), "can", "can0")
|
||||
|
||||
recv := socketcan.NewReceiver(conn)
|
||||
for recv.Receive() {
|
||||
frame := recv.Frame()
|
||||
fmt.Println(frame.String())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Sending CAN frames/messages
|
||||
|
||||
Sending CAN frames to a socketcan interface.
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// Error handling omitted to keep example simple
|
||||
|
||||
conn, _ := socketcan.DialContext(context.Background(), "can", "can0")
|
||||
|
||||
frame := can.Frame{}
|
||||
tx := socketcan.NewTransmitter(conn)
|
||||
_ = tx.TransmitFrame(context.Background(), frame)
|
||||
}
|
||||
```
|
||||
|
||||
### Generating Go code from a DBC file
|
||||
|
||||
It is possible to generate Go code from a `.dbc` file.
|
||||
|
||||
```
|
||||
$ go run github.com/Fisker-Inc/project-ai-can-go/cmd/cantool generate <dbc file root folder> <output folder>
|
||||
```
|
||||
|
||||
In order to generate Go code that makes sense, we currently perform some
|
||||
validations when parsing the DBC file so there may need to be some changes
|
||||
on the DBC file to make it work
|
||||
|
||||
After generating Go code we can marshal a message to a frame:
|
||||
|
||||
```go
|
||||
// import etruckcan "github.com/myproject/myrepo/gen"
|
||||
|
||||
auxMsg := etruckcan.NewAuxiliary().SetHeadLights(etruckcan.Auxiliary_HeadLights_LowBeam)
|
||||
frame := auxMsg.Frame()
|
||||
```
|
||||
|
||||
Or unmarshal a frame to a message:
|
||||
|
||||
```go
|
||||
// import etruckcan "github.com/myproject/myrepo/gen"
|
||||
|
||||
// Error handling omitted for simplicity
|
||||
_ := recv.Receive()
|
||||
frame := recv.Frame()
|
||||
|
||||
var auxMsg *etruckcan.Auxiliary
|
||||
_ = auxMsg.UnmarshalFrame(frame)
|
||||
|
||||
```
|
||||
Reference in New Issue
Block a user