2023-09-06 16:20:36 +08:00
|
|
|
|
package repository
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
2023-09-22 16:42:19 +08:00
|
|
|
|
|
2023-09-06 16:20:36 +08:00
|
|
|
|
"joylink.club/rtsssimulation/repository/model/proto"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 物理区段
|
|
|
|
|
type PhysicalSection struct {
|
|
|
|
|
Identity
|
|
|
|
|
|
|
|
|
|
len int32 //长度 mm
|
|
|
|
|
checkPoints []*CheckPoint //将此区段分隔出来的所有(非区段边界)检测点
|
|
|
|
|
|
|
|
|
|
// A/B端关联的设备端口(非道岔物理区段/道岔)
|
|
|
|
|
aRelation DevicePort
|
|
|
|
|
bRelation DevicePort
|
|
|
|
|
|
2023-09-20 15:14:38 +08:00
|
|
|
|
// 非道岔物理区段A/B端的公里标
|
2023-09-06 16:20:36 +08:00
|
|
|
|
aKm *proto.Kilometer
|
|
|
|
|
bKm *proto.Kilometer
|
|
|
|
|
|
|
|
|
|
turnouts []*Turnout //道岔物理区段关联的道岔
|
|
|
|
|
|
|
|
|
|
// 关联的设备(目前有信号机、应答器、(非区段边界)检测点)
|
|
|
|
|
devices []Identity
|
2023-09-20 15:14:38 +08:00
|
|
|
|
|
2023-09-22 10:29:35 +08:00
|
|
|
|
//aKm/bKm对应的LinkPosition
|
|
|
|
|
aLinkPosition *LinkPosition
|
|
|
|
|
bLinkPosition *LinkPosition
|
2023-09-20 18:20:56 +08:00
|
|
|
|
//在Link上的区间(根据aKm和bKm计算出的,start的offset一定小于end的offset)
|
2023-09-20 15:14:38 +08:00
|
|
|
|
startLinkPosition *LinkPosition
|
|
|
|
|
endLinkPosition *LinkPosition
|
2023-10-31 11:30:17 +08:00
|
|
|
|
|
|
|
|
|
//物理区段所属集中站
|
2023-09-06 16:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewPhysicalSection(id string) *PhysicalSection {
|
|
|
|
|
return &PhysicalSection{
|
|
|
|
|
Identity: identity{id, proto.DeviceType_DeviceType_PhysicalSection},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *PhysicalSection) PortNum() int {
|
|
|
|
|
return 2
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 10:29:35 +08:00
|
|
|
|
func (s *PhysicalSection) ALinkPosition() *LinkPosition {
|
|
|
|
|
return s.aLinkPosition
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *PhysicalSection) BLinkPosition() *LinkPosition {
|
|
|
|
|
return s.bLinkPosition
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *PhysicalSection) StartLinkPosition() *LinkPosition {
|
|
|
|
|
return s.startLinkPosition
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *PhysicalSection) EndLinkPosition() *LinkPosition {
|
|
|
|
|
return s.endLinkPosition
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *PhysicalSection) ARelation() DevicePort {
|
|
|
|
|
return s.aRelation
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *PhysicalSection) BRelation() DevicePort {
|
|
|
|
|
return s.bRelation
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 16:42:19 +08:00
|
|
|
|
func (s *PhysicalSection) AKilometer() *proto.Kilometer {
|
|
|
|
|
return s.aKm
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *PhysicalSection) BKilometer() *proto.Kilometer {
|
|
|
|
|
return s.bKm
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-23 17:39:39 +08:00
|
|
|
|
// IsAxleSection 判断是否为计轴区段
|
|
|
|
|
func (s *PhysicalSection) IsAxleSection() (bool, error) {
|
|
|
|
|
if len(s.checkPoints) > 0 {
|
|
|
|
|
axleCount := 0
|
|
|
|
|
for _, cp := range s.checkPoints {
|
|
|
|
|
if cp.pointType == proto.CheckPointType_AxleCounter {
|
|
|
|
|
axleCount++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if axleCount == len(s.checkPoints) {
|
|
|
|
|
return true, nil
|
|
|
|
|
} else if axleCount == 0 {
|
|
|
|
|
return false, nil
|
|
|
|
|
} else { //axleCount>0&&axleCount<len(s.checkPoints)
|
|
|
|
|
return false, fmt.Errorf("物理区段中检测点不纯")
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return false, fmt.Errorf("物理区段没有检测点")
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-06 16:20:36 +08:00
|
|
|
|
func (s *PhysicalSection) bindDevicePort(port proto.Port, devicePort DevicePort) error {
|
|
|
|
|
_, isSectionPort := devicePort.(*PhysicalSectionPort)
|
|
|
|
|
_, isTurnoutPort := devicePort.(*TurnoutPort)
|
|
|
|
|
if !isSectionPort && !isTurnoutPort {
|
|
|
|
|
return errors.New(fmt.Sprintf("物理区段不能与[%s]类型的设备端口关联", devicePort.Device().Type()))
|
|
|
|
|
}
|
|
|
|
|
switch port {
|
|
|
|
|
case proto.Port_A:
|
|
|
|
|
s.aRelation = devicePort
|
|
|
|
|
case proto.Port_B:
|
|
|
|
|
s.bRelation = devicePort
|
|
|
|
|
default:
|
|
|
|
|
return errors.New(fmt.Sprintf("物理区段无端口[%s]", port))
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 绑定区段边界公里标。(仅限非道岔物理区段调用)
|
|
|
|
|
func (s *PhysicalSection) bindBoundaryKm(km *proto.Kilometer, port proto.Port) error {
|
|
|
|
|
switch port {
|
|
|
|
|
case proto.Port_A:
|
|
|
|
|
s.aKm = km
|
|
|
|
|
case proto.Port_B:
|
|
|
|
|
s.bKm = km
|
|
|
|
|
default:
|
|
|
|
|
return errors.New(fmt.Sprintf("区段无端口[%s]", port))
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 道岔物理区段绑定道岔
|
|
|
|
|
func (s *PhysicalSection) bindTurnouts(turnouts ...*Turnout) {
|
|
|
|
|
for _, turnout := range turnouts {
|
|
|
|
|
s.turnouts = append(s.turnouts, turnout)
|
|
|
|
|
for _, cp := range turnout.checkPoints() {
|
|
|
|
|
s.bindDevices(cp)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *PhysicalSection) bindDevices(devices ...Identity) {
|
|
|
|
|
for _, device := range devices {
|
|
|
|
|
s.devices = append(s.devices, device)
|
|
|
|
|
cp, ok := device.(*CheckPoint)
|
|
|
|
|
if ok {
|
|
|
|
|
s.checkPoints = append(s.checkPoints, cp)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *PhysicalSection) findOtherDevicePort(port proto.Port) DevicePort {
|
|
|
|
|
switch port {
|
|
|
|
|
case proto.Port_A:
|
|
|
|
|
return s.bRelation
|
|
|
|
|
case proto.Port_B:
|
|
|
|
|
return s.aRelation
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *PhysicalSection) findOtherBoundaryKmByPort(port proto.Port) *proto.Kilometer {
|
|
|
|
|
switch port {
|
|
|
|
|
case proto.Port_A:
|
|
|
|
|
return s.bKm
|
|
|
|
|
case proto.Port_B:
|
|
|
|
|
return s.aKm
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *PhysicalSection) findBoundaryKmByPort(port proto.Port) *proto.Kilometer {
|
|
|
|
|
switch port {
|
|
|
|
|
case proto.Port_A:
|
|
|
|
|
return s.aKm
|
|
|
|
|
case proto.Port_B:
|
|
|
|
|
return s.bKm
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PhysicalSectionPort struct {
|
|
|
|
|
section *PhysicalSection
|
|
|
|
|
port proto.Port
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *PhysicalSectionPort) Port() proto.Port {
|
|
|
|
|
return p.port
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *PhysicalSectionPort) Device() PortedDevice {
|
|
|
|
|
return p.section
|
|
|
|
|
}
|