Initial motor sim
This commit is contained in:
parent
202aad293f
commit
bc740b4f31
2 changed files with 85 additions and 4 deletions
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type Config struct {
|
||||||
Id uint16
|
Id uint16
|
||||||
Port uint16
|
Port uint16
|
||||||
Min_pos float64
|
Min_pos float64
|
||||||
|
@ -21,10 +21,16 @@ type config struct {
|
||||||
Accel float64
|
Accel float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type State struct {
|
||||||
|
Angle float64
|
||||||
|
Velocity float64
|
||||||
|
Error string //Error message if any
|
||||||
|
}
|
||||||
|
|
||||||
var(
|
var(
|
||||||
motorID uint16 = 0 //Requested ID
|
motorID uint16 = 0 //Requested ID
|
||||||
ip string = "localhost" //localhost=127.0.0.1
|
ip string = "localhost" //localhost=127.0.0.1
|
||||||
curr_config config //Current config of the motor
|
curr_config Config //Current config of the motor
|
||||||
)
|
)
|
||||||
|
|
||||||
// motorCmd represents the motor command
|
// motorCmd represents the motor command
|
||||||
|
|
|
@ -6,6 +6,7 @@ package motor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
@ -17,6 +18,11 @@ import (
|
||||||
pb "github.com/AntoineHX/multi-motors-controller/src/proto"
|
pb "github.com/AntoineHX/multi-motors-controller/src/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var(
|
||||||
|
stateChan chan State // State channel of the simulation
|
||||||
|
cmdVelChan chan float64 // Command channel of the simulation
|
||||||
|
)
|
||||||
|
|
||||||
//Cobra CLI
|
//Cobra CLI
|
||||||
// serveCmd represents the serve command
|
// serveCmd represents the serve command
|
||||||
var serveCmd = &cobra.Command{
|
var serveCmd = &cobra.Command{
|
||||||
|
@ -27,6 +33,7 @@ var serveCmd = &cobra.Command{
|
||||||
fmt.Println("serve called with ID ", cmd.Flag("id").Value)
|
fmt.Println("serve called with ID ", cmd.Flag("id").Value)
|
||||||
// fmt.Println(cmd.CommandPath())
|
// fmt.Println(cmd.CommandPath())
|
||||||
updateConfig()
|
updateConfig()
|
||||||
|
init_sim()
|
||||||
serve()
|
serve()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -84,11 +91,24 @@ type server struct {
|
||||||
//TODO: Fix compiling issue with google.protobuf.Empty message
|
//TODO: Fix compiling issue with google.protobuf.Empty message
|
||||||
func (s *server) SetVolicty(ctx context.Context, in *pb.Velocity) (*pb.Empty, error) {
|
func (s *server) SetVolicty(ctx context.Context, in *pb.Velocity) (*pb.Empty, error) {
|
||||||
log.Printf("Received: %v", in.GetVelocity())
|
log.Printf("Received: %v", in.GetVelocity())
|
||||||
|
select{
|
||||||
|
case cmdVelChan<-in.GetVelocity(): //Send command
|
||||||
return &pb.Empty{}, nil
|
return &pb.Empty{}, nil
|
||||||
|
default: //Drop command
|
||||||
|
log.Printf("Failed to send command to simulation")
|
||||||
|
return &pb.Empty{}, nil //TODO: Return error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) GetData(ctx context.Context, in *pb.Empty) (*pb.MotorData, error) {
|
func (s *server) GetData(ctx context.Context, in *pb.Empty) (*pb.MotorData, error) {
|
||||||
return &pb.MotorData{Angle: 0, Velocity: 0, Error: ""}, nil
|
var state State
|
||||||
|
select {
|
||||||
|
case state = <-stateChan :
|
||||||
|
return &pb.MotorData{Angle: state.Angle, Velocity: state.Velocity, Error: state.Error}, nil
|
||||||
|
default:
|
||||||
|
log.Printf("No data available")
|
||||||
|
return &pb.MotorData{Angle: 0, Velocity: 0, Error: "No Data"}, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func serve() {
|
func serve() {
|
||||||
|
@ -103,3 +123,58 @@ func serve() {
|
||||||
log.Fatalf("failed to serve: %v", err)
|
log.Fatalf("failed to serve: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Motor sim
|
||||||
|
func init_sim(){
|
||||||
|
//Initial state
|
||||||
|
var state State
|
||||||
|
state.Angle = 0
|
||||||
|
state.Velocity = 0
|
||||||
|
state.Error = ""
|
||||||
|
|
||||||
|
//Channels //TODO: Add buffer ?
|
||||||
|
stateChan = make(chan State) // State channel of the simulation
|
||||||
|
cmdVelChan = make(chan float64)// Command channel of the simulation
|
||||||
|
|
||||||
|
go motor_sim(state, curr_config, 1) //Run sim at 10Hz
|
||||||
|
//close(cmdVelChan) //Stop sim
|
||||||
|
}
|
||||||
|
|
||||||
|
func motor_sim(state_init State, config Config, sim_freq float64){
|
||||||
|
state:=state_init
|
||||||
|
cmd_vel:=state.Velocity
|
||||||
|
ok:=true
|
||||||
|
for {
|
||||||
|
|
||||||
|
//Get command velocity from channel (non-blocking)
|
||||||
|
select{
|
||||||
|
case cmd_vel = <- cmdVelChan:
|
||||||
|
// check if channel is closed
|
||||||
|
if !ok { //Stop sim
|
||||||
|
log.Printf("Command channel closed. Stopping simulation...")
|
||||||
|
close(stateChan)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: //No command, do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
// cmdVelChan
|
||||||
|
//Update state
|
||||||
|
state.Velocity = cmd_vel //Infinite acceleration
|
||||||
|
state.Angle += state.Velocity * 1/sim_freq //Neglect computation delay for delta time
|
||||||
|
|
||||||
|
//TODO: Error check
|
||||||
|
|
||||||
|
//Send new state to channel (non-blocking)
|
||||||
|
select{
|
||||||
|
case stateChan <- state:
|
||||||
|
break;
|
||||||
|
default: //No message sent (buffer full/no receiver)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Motor state: %+v", state)
|
||||||
|
//Wait for next iteration
|
||||||
|
time.Sleep(time.Duration(float64(time.Second)/sim_freq))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue