2019-11-30 18:03:07 +00:00
package arduino
import (
"bufio"
"fmt"
2022-09-02 09:44:14 +00:00
"github.com/cyrilix/robocar-arduino/pkg/tools"
2020-01-01 16:12:18 +00:00
"github.com/cyrilix/robocar-protobuf/go/events"
mqtt "github.com/eclipse/paho.mqtt.golang"
2022-01-03 09:24:06 +00:00
"google.golang.org/protobuf/proto"
2022-01-17 17:40:25 +00:00
"math"
2019-11-30 18:03:07 +00:00
"net"
2020-01-01 16:12:18 +00:00
"sync"
2019-11-30 18:03:07 +00:00
"testing"
"time"
)
2022-01-17 17:40:25 +00:00
const (
MinPwmAngle = 999.0
MaxPwmAngle = 1985.0
)
var (
MiddlePwmAngle = int ( ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle )
)
2019-11-30 18:03:07 +00:00
func TestArduinoPart_Update ( t * testing . T ) {
2020-01-01 16:12:18 +00:00
oldPublish := publish
defer func ( ) { publish = oldPublish } ( )
2022-06-13 13:21:58 +00:00
publish = func ( client mqtt . Client , topic string , payload [ ] byte ) { }
2020-01-01 16:12:18 +00:00
2019-11-30 18:03:07 +00:00
ln , err := net . Listen ( "tcp" , ":8080" )
if err != nil {
t . Fatalf ( "unable to init connection for test" )
}
2020-01-01 16:12:18 +00:00
defer func ( ) {
if err := ln . Close ( ) ; err != nil {
t . Errorf ( "unable to close resource: %v" , err )
}
} ( )
2019-11-30 18:03:07 +00:00
2020-01-01 16:12:18 +00:00
serialClient , err := net . Dial ( "tcp" , "localhost:8080" )
2019-11-30 18:03:07 +00:00
if err != nil {
t . Fatalf ( "unable to init connection for test" )
}
2020-01-01 16:12:18 +00:00
defer func ( ) {
if err := serialClient . Close ( ) ; err != nil {
t . Errorf ( "unable to close resource: %v" , err )
}
} ( )
2019-11-30 18:03:07 +00:00
conn , err := ln . Accept ( )
if err != nil {
t . Fatalf ( "unable to init connection for test" )
}
2020-01-01 16:12:18 +00:00
defer func ( ) {
if err := conn . Close ( ) ; err != nil {
t . Errorf ( "unable to close resource: %v" , err )
}
} ( )
2019-11-30 18:03:07 +00:00
2022-08-10 14:49:58 +00:00
defaultPwmThrottleConfig := NewPWMConfig ( MinPwmThrottle , MaxPwmThrottle )
2022-09-02 09:44:14 +00:00
a := Part { client : nil , serial : conn , pubFrequency : 100 ,
pwmSteeringConfig : NewAsymetricPWMConfig ( MinPwmAngle , MaxPwmAngle , MiddlePwmAngle ) ,
pwmThrottleConfig : & DefaultPwmThrottle ,
2023-11-02 17:50:14 +00:00
pwmMaxThrottleCtrlConfig : & DefaultPwmThrottle ,
2022-09-02 09:44:14 +00:00
throttleFeedbackThresholds : tools . NewThresholdConfig ( ) ,
}
2020-01-01 16:12:18 +00:00
go func ( ) {
err := a . Start ( )
if err != nil {
t . Errorf ( "unsable to start part: %v" , err )
t . Fail ( )
}
} ( )
2019-11-30 18:03:07 +00:00
2022-09-02 09:44:14 +00:00
channel1 , channel2 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 := 678 , 910 , 1012 , 1678 , 1910 , 112 , 0 , 0 , 0
2019-11-30 18:03:07 +00:00
cases := [ ] struct {
2023-11-02 17:50:14 +00:00
name , content string
throttlePwmConfig * PWMConfig
expectedThrottle , expectedSteering , expectedMaxThrottleCtrl float32
expectedDriveMode events . DriveMode
expectedSwitchRecord bool
2019-11-30 18:03:07 +00:00
} {
{ "Good value" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12345,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 ,
2022-06-13 13:21:58 +00:00
events . DriveMode_USER , false } ,
2022-08-18 16:22:24 +00:00
{ "Invalid line" ,
2022-06-13 13:21:58 +00:00
"12350,invalid line\n" , defaultPwmThrottleConfig ,
2023-11-02 17:50:14 +00:00
- 1. , - 1. , 0.01 , events . DriveMode_INVALID , false } ,
2019-11-30 18:03:07 +00:00
{ "Switch record on" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12355,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , channel3 , channel4 , 998 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_USER , true } ,
2019-11-30 18:03:07 +00:00
{ "Switch record off" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12360,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , channel3 , channel4 , 1987 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "Switch record off" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12365,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , channel3 , channel4 , 1850 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "Switch record on" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12370,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , channel3 , channel4 , 1003 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_USER , true } ,
2019-11-30 18:03:07 +00:00
{ "DriveMode: user" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12375,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , channel3 , channel4 , channel5 , 998 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "DriveMode: pilot" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12380,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , channel3 , channel4 , channel5 , 1987 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_PILOT , false } ,
2019-11-30 18:03:07 +00:00
{ "DriveMode: pilot" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12385,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , channel3 , channel4 , channel5 , 1850 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_PILOT , false } ,
2019-11-30 18:03:07 +00:00
// DriveMode: user
{ "DriveMode: user" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12390,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , channel3 , channel4 , channel5 , 1003 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_USER , false } ,
2023-10-15 09:33:10 +00:00
// DriveMode: copilot
{ "DriveMode: copilot" ,
fmt . Sprintf ( "12390,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , channel3 , channel4 , channel5 , 1250 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_COPILOT , false } ,
2019-11-30 18:03:07 +00:00
2022-09-02 09:44:14 +00:00
{ "Sterring: over left" , fmt . Sprintf ( "12395,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , 99 , channel2 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "Sterring: left" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12400,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , int ( MinPwmAngle + 40 ) , channel2 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 0.92 , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "Sterring: middle" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12405,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , 1450 , channel2 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 0.09 , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "Sterring: right" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12410,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , 1958 , channel2 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , 0.95 , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "Sterring: over right" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12415,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , 2998 , channel2 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , 1. , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "Throttle: over down" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12420,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , 99 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "Throttle: down" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12425,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , 998 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 0.95 , - 1. , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "Throttle: stop" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12430,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , 1450 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
NewPWMConfig ( 1000 , 1900 ) , 0.0 , - 1. , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "Throttle: up" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12435,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , 1948 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , 0.99 , - 1. , 0.01 , events . DriveMode_USER , false } ,
2019-11-30 18:03:07 +00:00
{ "Throttle: over up" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12440,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , 2998 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , 1. , - 1. , 0.01 , events . DriveMode_USER , false } ,
2022-06-13 16:35:27 +00:00
{ "Throttle: zero not middle" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12440,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , 1600 , channel3 , channel4 , channel5 , channel6 , channel7 , channel8 , channel9 ) ,
2022-08-10 14:49:58 +00:00
& PWMConfig { 1000 , 1700 , 1500 } ,
2023-11-02 17:50:14 +00:00
0.5 , - 1. , 0.01 , events . DriveMode_USER , false } ,
{ "MaxThrottleCtrl: Too low value" ,
fmt . Sprintf ( "12440,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , 100 , channel4 , channel5 , channel6 , 2000 , 2008 , channel9 ) ,
defaultPwmThrottleConfig , - 1. , - 1 , 0. , events . DriveMode_USER , false } ,
{ "MaxThrottleCtrl: low value" ,
fmt . Sprintf ( "12440,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , 1050 , channel4 , channel5 , channel6 , 2000 , 2008 , channel9 ) ,
defaultPwmThrottleConfig , - 1. , - 1 , 0.05 , events . DriveMode_USER , false } ,
{ "MaxThrottleCtrl: High value" ,
fmt . Sprintf ( "12440,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , 1900 , channel4 , channel5 , channel6 , 2000 , 2008 , channel9 ) ,
defaultPwmThrottleConfig , - 1. , - 1 , 0.91 , events . DriveMode_USER , false } ,
{ "MaxThrottleCtrl: Too High value" ,
fmt . Sprintf ( "12440,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel2 , 4005 , channel4 , channel5 , channel6 , 2000 , 2008 , channel9 ) ,
defaultPwmThrottleConfig , - 1. , - 1 , 1 , events . DriveMode_USER , false } ,
2022-08-18 16:22:24 +00:00
{ "Drive Mode: user" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12430,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel6 , channel3 , channel4 , channel5 , 900 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_USER , false } ,
2022-08-18 16:22:24 +00:00
{ "Drive Mode: pilot" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12430,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel6 , channel3 , channel4 , channel5 , 1950 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_PILOT , false } ,
2022-08-18 16:22:24 +00:00
{ "Drive Mode: no value" ,
2022-09-02 09:44:14 +00:00
fmt . Sprintf ( "12430,%d,%d,%d,%d,%d,%d,%d,%d,%d,50\n" , channel1 , channel6 , channel3 , channel4 , channel5 , - 1 , channel7 , channel8 , channel9 ) ,
2023-11-02 17:50:14 +00:00
defaultPwmThrottleConfig , - 1. , - 1. , 0.01 , events . DriveMode_INVALID , false } ,
2019-11-30 18:03:07 +00:00
}
for _ , c := range cases {
2022-08-09 15:00:58 +00:00
t . Run ( c . name , func ( t * testing . T ) {
w := bufio . NewWriter ( serialClient )
_ , err := w . WriteString ( c . content )
if err != nil {
t . Errorf ( "unable to send test content: %v" , c . content )
}
err = w . Flush ( )
if err != nil {
t . Error ( "unable to flush content" )
}
a . pwmThrottleConfig = c . throttlePwmConfig
2022-08-18 16:22:24 +00:00
a . driveMode = events . DriveMode_INVALID
2022-08-09 15:00:58 +00:00
time . Sleep ( 10 * time . Millisecond )
a . mutex . Lock ( )
a . mutex . Unlock ( )
2022-08-10 14:49:58 +00:00
if fmt . Sprintf ( "%0.2f" , a . Throttle ( ) ) != fmt . Sprintf ( "%0.2f" , c . expectedThrottle ) {
t . Errorf ( "%s: bad throttle value, expected: %0.2f, actual: %.2f" , c . name , c . expectedThrottle , a . Throttle ( ) )
2022-08-09 15:00:58 +00:00
}
2022-08-10 14:49:58 +00:00
if fmt . Sprintf ( "%0.2f" , a . Steering ( ) ) != fmt . Sprintf ( "%0.2f" , c . expectedSteering ) {
t . Errorf ( "%s: bad steering value, expected: %0.2f, actual: %.2f" , c . name , c . expectedSteering , a . Steering ( ) )
2022-08-09 15:00:58 +00:00
}
2023-11-02 17:50:14 +00:00
if fmt . Sprintf ( "%0.2f" , a . MaxThrottleCtrl ( ) ) != fmt . Sprintf ( "%0.2f" , c . expectedMaxThrottleCtrl ) {
t . Errorf ( "%s: bad MaxThrottleCtrl value, expected: %0.2f, actual: %.2f" , c . name , c . expectedMaxThrottleCtrl , a . MaxThrottleCtrl ( ) )
}
2022-08-10 14:49:58 +00:00
if a . DriveMode ( ) != c . expectedDriveMode {
t . Errorf ( "%s: bad drive mode, expected: %v, actual:%v" , c . name , c . expectedDriveMode , a . DriveMode ( ) )
2022-08-09 15:00:58 +00:00
}
2022-08-10 14:49:58 +00:00
if a . SwitchRecord ( ) != c . expectedSwitchRecord {
t . Errorf ( "%s: bad switch record, expected: %v, actual:%v" , c . name , c . expectedSwitchRecord , a . SwitchRecord ( ) )
2022-08-09 15:00:58 +00:00
}
} )
2019-11-30 18:03:07 +00:00
}
}
2019-12-01 21:35:19 +00:00
func TestPublish ( t * testing . T ) {
2020-01-01 16:12:18 +00:00
oldPublish := publish
defer func ( ) { publish = oldPublish } ( )
var muPublishedEvents sync . Mutex
pulishedEvents := make ( map [ string ] [ ] byte )
2022-06-13 13:21:58 +00:00
publish = func ( client mqtt . Client , topic string , payload [ ] byte ) {
2020-01-01 16:12:18 +00:00
muPublishedEvents . Lock ( )
defer muPublishedEvents . Unlock ( )
2022-06-13 13:21:58 +00:00
pulishedEvents [ topic ] = payload
2020-01-01 16:12:18 +00:00
}
2019-12-01 21:35:19 +00:00
ln , err := net . Listen ( "tcp" , ":8080" )
if err != nil {
t . Fatalf ( "unable to init connection for test" )
}
defer ln . Close ( )
client , err := net . Dial ( "tcp" , "localhost:8080" )
if err != nil {
t . Fatalf ( "unable to init connection for test" )
}
defer client . Close ( )
conn , err := ln . Accept ( )
if err != nil {
t . Fatalf ( "unable to init connection for test" )
}
defer conn . Close ( )
pubFrequency := 100.
2020-01-27 18:21:26 +00:00
a := Part {
2022-09-02 09:44:14 +00:00
client : nil ,
serial : conn ,
pubFrequency : pubFrequency ,
throttleTopic : "car/part/arduino/throttle/target" ,
2023-11-02 17:50:14 +00:00
maxThrottleCtrlTopic : "car/part/arduino/throttle/max" ,
2022-09-02 09:44:14 +00:00
steeringTopic : "car/part/arduino/steering" ,
driveModeTopic : "car/part/arduino/drive_mode" ,
switchRecordTopic : "car/part/arduino/switch_record" ,
throttleFeedbackTopic : "car/part/arduino/throttle/feedback" ,
cancel : make ( chan interface { } ) ,
2020-01-27 18:21:26 +00:00
}
2019-12-01 21:35:19 +00:00
go a . Start ( )
defer a . Stop ( )
cases := [ ] struct {
2022-09-02 09:44:14 +00:00
throttle , steering float32
driveMode events . DriveMode
throttleFeedback float32
2023-11-02 17:50:14 +00:00
maxThrottleCtrl float32
2022-09-02 09:44:14 +00:00
switchRecord bool
expectedThrottle events . ThrottleMessage
expectedSteering events . SteeringMessage
expectedDriveMode events . DriveModeMessage
expectedSwitchRecord events . SwitchRecordMessage
expectedThrottleFeedback events . ThrottleMessage
2023-11-02 17:50:14 +00:00
expectedMaxThrottleCtrl events . ThrottleMessage
2019-12-01 21:35:19 +00:00
} {
2023-11-02 17:50:14 +00:00
{ - 1 , 1 , events . DriveMode_USER , 0.3 , 0.5 , true ,
2020-01-01 16:12:18 +00:00
events . ThrottleMessage { Throttle : - 1. , Confidence : 1. } ,
events . SteeringMessage { Steering : 1.0 , Confidence : 1. } ,
events . DriveModeMessage { DriveMode : events . DriveMode_USER } ,
events . SwitchRecordMessage { Enabled : false } ,
2022-09-02 09:44:14 +00:00
events . ThrottleMessage { Throttle : 0.3 , Confidence : 1. } ,
2023-11-02 17:50:14 +00:00
events . ThrottleMessage { Throttle : 0.5 , Confidence : 1. } ,
2020-01-01 16:12:18 +00:00
} ,
2023-11-02 17:50:14 +00:00
{ 0 , 0 , events . DriveMode_PILOT , 0.4 , 0.5 , false ,
2020-01-01 16:12:18 +00:00
events . ThrottleMessage { Throttle : 0. , Confidence : 1. } ,
events . SteeringMessage { Steering : 0. , Confidence : 1. } ,
events . DriveModeMessage { DriveMode : events . DriveMode_PILOT } ,
events . SwitchRecordMessage { Enabled : true } ,
2022-09-02 09:44:14 +00:00
events . ThrottleMessage { Throttle : 0.4 , Confidence : 1. } ,
2023-11-02 17:50:14 +00:00
events . ThrottleMessage { Throttle : 0.5 , Confidence : 1. } ,
2020-01-01 16:12:18 +00:00
} ,
2023-11-02 17:50:14 +00:00
{ 0.87 , - 0.58 , events . DriveMode_PILOT , 0.5 , 0.5 , false ,
2020-01-01 16:12:18 +00:00
events . ThrottleMessage { Throttle : 0.87 , Confidence : 1. } ,
events . SteeringMessage { Steering : - 0.58 , Confidence : 1. } ,
events . DriveModeMessage { DriveMode : events . DriveMode_PILOT } ,
events . SwitchRecordMessage { Enabled : true } ,
2022-09-02 09:44:14 +00:00
events . ThrottleMessage { Throttle : 0.5 , Confidence : 1. } ,
2023-11-02 17:50:14 +00:00
events . ThrottleMessage { Throttle : 0.5 , Confidence : 1. } ,
2020-01-01 16:12:18 +00:00
} ,
2019-12-01 21:35:19 +00:00
}
for _ , c := range cases {
a . mutex . Lock ( )
a . throttle = c . throttle
a . steering = c . steering
2023-11-02 17:50:14 +00:00
a . maxThrottleCtrl = c . maxThrottleCtrl
2019-12-01 21:35:19 +00:00
a . driveMode = c . driveMode
a . ctrlRecord = c . switchRecord
2022-09-02 09:44:14 +00:00
a . throttleFeedback = c . throttleFeedback
2019-12-01 21:35:19 +00:00
a . mutex . Unlock ( )
2022-09-02 09:44:14 +00:00
time . Sleep ( time . Second / time . Duration ( int ( pubFrequency ) ) * 2 )
2019-12-01 21:35:19 +00:00
2020-01-01 16:12:18 +00:00
var throttleMsg events . ThrottleMessage
muPublishedEvents . Lock ( )
2022-09-02 09:44:14 +00:00
unmarshalMsg ( t , pulishedEvents [ "car/part/arduino/throttle/target" ] , & throttleMsg )
2020-01-01 16:12:18 +00:00
muPublishedEvents . Unlock ( )
if throttleMsg . String ( ) != c . expectedThrottle . String ( ) {
2022-09-02 09:44:14 +00:00
t . Errorf ( "msg(car/part/arduino/throttle/target): %v, wants %v" , throttleMsg . String ( ) , c . expectedThrottle . String ( ) )
2019-12-01 21:35:19 +00:00
}
2020-01-01 16:12:18 +00:00
var steeringMsg events . SteeringMessage
muPublishedEvents . Lock ( )
unmarshalMsg ( t , pulishedEvents [ "car/part/arduino/steering" ] , & steeringMsg )
muPublishedEvents . Unlock ( )
if steeringMsg . String ( ) != c . expectedSteering . String ( ) {
2022-09-02 09:44:14 +00:00
t . Errorf ( "msg(car/part/arduino/steering): %v, wants %v" , steeringMsg . String ( ) , c . expectedSteering . String ( ) )
2019-12-01 21:35:19 +00:00
}
2020-01-01 16:12:18 +00:00
var driveModeMsg events . DriveModeMessage
muPublishedEvents . Lock ( )
unmarshalMsg ( t , pulishedEvents [ "car/part/arduino/drive_mode" ] , & driveModeMsg )
muPublishedEvents . Unlock ( )
if driveModeMsg . String ( ) != c . expectedDriveMode . String ( ) {
2022-09-02 09:44:14 +00:00
t . Errorf ( "msg(car/part/arduino/drive_mode): %v, wants %v" , driveModeMsg . String ( ) , c . expectedDriveMode . String ( ) )
2019-12-01 21:35:19 +00:00
}
2020-01-01 16:12:18 +00:00
var switchRecordMsg events . SwitchRecordMessage
muPublishedEvents . Lock ( )
unmarshalMsg ( t , pulishedEvents [ "car/part/arduino/switch_record" ] , & switchRecordMsg )
muPublishedEvents . Unlock ( )
if switchRecordMsg . String ( ) != c . expectedSwitchRecord . String ( ) {
2022-09-02 09:44:14 +00:00
t . Errorf ( "msg(car/part/arduino/switch_record): %v, wants %v" , switchRecordMsg . String ( ) , c . expectedSwitchRecord . String ( ) )
}
var throttleFeedbackMsg events . ThrottleMessage
muPublishedEvents . Lock ( )
unmarshalMsg ( t , pulishedEvents [ "car/part/arduino/throttle/feedback" ] , & throttleFeedbackMsg )
muPublishedEvents . Unlock ( )
if throttleFeedbackMsg . String ( ) != c . expectedThrottleFeedback . String ( ) {
t . Errorf ( "msg(car/part/arduino/throttle/feedback): %v, wants %v" , throttleFeedbackMsg . String ( ) , c . expectedThrottleFeedback . String ( ) )
2019-12-01 21:35:19 +00:00
}
2023-11-02 17:50:14 +00:00
var maxThrottleCtrlMsg events . ThrottleMessage
muPublishedEvents . Lock ( )
unmarshalMsg ( t , pulishedEvents [ "car/part/arduino/throttle/max" ] , & maxThrottleCtrlMsg )
muPublishedEvents . Unlock ( )
if maxThrottleCtrlMsg . String ( ) != c . expectedMaxThrottleCtrl . String ( ) {
t . Errorf ( "msg(car/part/arduino/throttle/max): %v, wants %v" , maxThrottleCtrlMsg . String ( ) , c . expectedMaxThrottleCtrl . String ( ) )
}
2019-12-01 21:35:19 +00:00
}
}
2020-01-01 16:12:18 +00:00
func unmarshalMsg ( t * testing . T , payload [ ] byte , msg proto . Message ) {
err := proto . Unmarshal ( payload , msg )
if err != nil {
t . Errorf ( "unable to unmarshal protobuf content to %T: %v" , msg , err )
}
}
2022-01-17 17:40:25 +00:00
func Test_convertPwmSteeringToPercent ( t * testing . T ) {
type args struct {
2022-08-10 14:49:58 +00:00
value int
steeringConfig * PWMConfig
2022-01-17 17:40:25 +00:00
}
tests := [ ] struct {
name string
args args
want float32
} {
{
name : "middle" ,
args : args {
2022-08-10 14:49:58 +00:00
value : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : 0. ,
} ,
{
name : "left" ,
args : args {
2022-08-10 14:49:58 +00:00
value : MinPwmAngle ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : - 1. ,
} ,
{
name : "mid-left" ,
args : args {
2022-08-10 14:49:58 +00:00
value : int ( math . Round ( ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle - ( MaxPwmAngle - MinPwmAngle ) / 4 ) ) ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : - 0.4989858 ,
} ,
{
name : "over left" ,
args : args {
2022-08-10 14:49:58 +00:00
value : MinPwmAngle - 100 ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : - 1. ,
} ,
{
name : "right" ,
args : args {
2022-08-10 14:49:58 +00:00
value : MaxPwmAngle ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : 1. ,
} ,
{
name : "mid-right" ,
args : args {
2022-08-10 14:49:58 +00:00
value : int ( math . Round ( ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle + ( MaxPwmAngle - MinPwmAngle ) / 4 ) ) ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : 0.5010142 ,
} ,
{
name : "over right" ,
args : args {
2022-08-10 14:49:58 +00:00
value : MaxPwmAngle + 100 ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : 1. ,
} ,
{
name : "asymetric middle" ,
args : args {
2022-08-10 14:49:58 +00:00
value : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle + 100 ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle + 100 ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : 0. ,
} ,
{
name : "asymetric mid-left" ,
args : args {
2022-08-10 14:49:58 +00:00
value : int ( math . Round ( ( ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle + 100 - MinPwmAngle ) / 2 ) + MinPwmAngle ) ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle + 100 ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : - 0.49915683 ,
} ,
{
name : "asymetric left" ,
args : args {
2022-08-10 14:49:58 +00:00
value : MinPwmAngle ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle + 100 ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : - 1. ,
} ,
{
name : "asymetric mid-right" ,
args : args {
2022-08-10 14:49:58 +00:00
value : int ( math . Round ( ( MaxPwmAngle - ( MaxPwmAngle - ( ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle + 100 ) ) / 2 ) ) ) ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle + 100 ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : 0.50127226 ,
} ,
{
name : "asymetric right" ,
args : args {
2022-08-10 14:49:58 +00:00
value : MaxPwmAngle ,
steeringConfig : & PWMConfig {
Middle : ( MaxPwmAngle - MinPwmAngle ) / 2 + MinPwmAngle + 100 ,
Min : MinPwmAngle ,
Max : MaxPwmAngle ,
} ,
2022-01-17 17:40:25 +00:00
} ,
want : 1. ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
2023-11-02 17:50:14 +00:00
if got := convertPwmToPercent ( tt . args . value , tt . args . steeringConfig ) ; got != tt . want {
t . Errorf ( "convertPwmToPercent() = %v, want %v" , got , tt . want )
2022-01-17 17:40:25 +00:00
}
} )
}
}
2022-09-02 09:44:14 +00:00
func TestPart_convertPwmFeedBackToPercent ( t * testing . T ) {
type fields struct {
}
type args struct {
value int
}
tests := [ ] struct {
name string
fields fields
args args
want float32
} {
{
name : "big value -> 0%" ,
args : args { value : 1234567 } ,
want : 0. ,
} ,
{
name : "very slow" ,
args : args { 10000 } ,
want : 0. ,
} ,
{
name : "0.07 limit" ,
args : args { 8700 } ,
want : 0.07 ,
} ,
{
name : "0.075" ,
args : args { value : 8700 - ( 8700 - 4800 ) / 2 } ,
want : 0.075 ,
} ,
{
name : "0.08" ,
args : args { value : 4800 } ,
want : 0.08 ,
} ,
{
name : "1.0" ,
args : args { value : 548 } ,
want : 1. ,
} ,
{
name : "under lower limit" ,
args : args { value : 520 } ,
want : 1. ,
} ,
{
name : "invalid value" ,
args : args { value : 499 } ,
want : 0. ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
a := & Part { throttleFeedbackThresholds : tools . NewThresholdConfig ( ) }
if got := a . convertPwmFeedBackToPercent ( tt . args . value ) ; got != tt . want {
t . Errorf ( "convertPwmFeedBackToPercent() = %v, want %v" , got , tt . want )
}
} )
}
}