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"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
type Config struct {
|
||||
Id uint16
|
||||
Port uint16
|
||||
Min_pos float64
|
||||
|
@ -21,10 +21,16 @@ type config struct {
|
|||
Accel float64
|
||||
}
|
||||
|
||||
type State struct {
|
||||
Angle float64
|
||||
Velocity float64
|
||||
Error string //Error message if any
|
||||
}
|
||||
|
||||
var(
|
||||
motorID uint16 = 0 //Requested ID
|
||||
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
|
||||
|
|
|
@ -6,6 +6,7 @@ package motor
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
@ -17,6 +18,11 @@ import (
|
|||
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
|
||||
// serveCmd represents the serve 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(cmd.CommandPath())
|
||||
updateConfig()
|
||||
init_sim()
|
||||
serve()
|
||||
},
|
||||
}
|
||||
|
@ -84,11 +91,24 @@ type server struct {
|
|||
//TODO: Fix compiling issue with google.protobuf.Empty message
|
||||
func (s *server) SetVolicty(ctx context.Context, in *pb.Velocity) (*pb.Empty, error) {
|
||||
log.Printf("Received: %v", in.GetVelocity())
|
||||
return &pb.Empty{}, nil
|
||||
select{
|
||||
case cmdVelChan<-in.GetVelocity(): //Send command
|
||||
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) {
|
||||
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() {
|
||||
|
@ -102,4 +122,59 @@ func serve() {
|
|||
if err := s.Serve(lis); err != nil {
|
||||
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